Merge branch 'master' into faiz_cs

# Conflicts:
#	lib/classes/consts.dart
#	lib/ui/landing/dashboard_screen.dart
#	lib/ui/marathon/marathon_intro_screen.dart
#	lib/ui/marathon/marathon_provider.dart
#	lib/ui/marathon/marathon_screen.dart
#	lib/ui/marathon/marathon_winner_selection.dart
#	lib/ui/marathon/widgets/question_card.dart
#	pubspec.yaml
faiz_marathon_signalR_critical
Faiz Hashmi 2 years ago
commit 2f825151a0

@ -18,8 +18,7 @@ class APIError {
APIError(this.errorCode, this.errorMessage);
Map<String, dynamic> toJson() =>
{'errorCode': errorCode, 'errorMessage': errorMessage};
Map<String, dynamic> toJson() => {'errorCode': errorCode, 'errorMessage': errorMessage};
@override
String toString() {
@ -54,8 +53,7 @@ APIException _throwAPIException(Response response) {
return APIException(APIException.INTERNAL_SERVER_ERROR);
case 444:
var downloadUrl = response.headers["location"];
return APIException(APIException.UPGRADE_REQUIRED,
arguments: downloadUrl);
return APIException(APIException.UPGRADE_REQUIRED, arguments: downloadUrl);
default:
return APIException(APIException.OTHER);
}
@ -68,13 +66,8 @@ class ApiClient {
factory ApiClient() => _instance;
Future<U> postJsonForObject<T, U>(
FactoryConstructor<U> factoryConstructor, String url, T jsonObject,
{String? token,
Map<String, dynamic>? queryParameters,
Map<String, String>? headers,
int retryTimes = 0,
bool isFormData = false}) async {
Future<U> postJsonForObject<T, U>(FactoryConstructor<U> factoryConstructor, String url, T jsonObject,
{String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0, bool isFormData = false}) async {
var _headers = {'Accept': 'application/json'};
if (headers != null && headers.isNotEmpty) {
_headers.addAll(headers);
@ -84,12 +77,7 @@ class ApiClient {
var bodyJson = json.encode(jsonObject);
print("body:$bodyJson");
}
var response = await postJsonForResponse(url, jsonObject,
token: token,
queryParameters: queryParameters,
headers: _headers,
retryTimes: retryTimes,
isFormData: isFormData);
var response = await postJsonForResponse(url, jsonObject, token: token, queryParameters: queryParameters, headers: _headers, retryTimes: retryTimes, isFormData: isFormData);
// try {
if (!kReleaseMode) {
logger.i("res: " + response.body);
@ -102,8 +90,7 @@ class ApiClient {
return factoryConstructor(jsonData);
} else {
APIError? apiError;
apiError =
APIError(jsonData['ErrorCode'], jsonData['ErrorEndUserMessage']);
apiError = APIError(jsonData['ErrorCode'], jsonData['ErrorEndUserMessage']);
throw APIException(APIException.BAD_REQUEST, error: apiError);
}
// } catch (ex) {
@ -116,11 +103,7 @@ class ApiClient {
}
Future<Response> postJsonForResponse<T>(String url, T jsonObject,
{String? token,
Map<String, dynamic>? queryParameters,
Map<String, String>? headers,
int retryTimes = 0,
bool isFormData = false}) async {
{String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0, bool isFormData = false}) async {
String? requestBody;
late Map<String, String> stringObj;
if (jsonObject != null) {
@ -134,22 +117,13 @@ class ApiClient {
if (isFormData) {
headers = {'Content-Type': 'application/x-www-form-urlencoded'};
stringObj = ((jsonObject ?? {}) as Map<String, dynamic>)
.map((key, value) => MapEntry(key, value?.toString() ?? ""));
stringObj = ((jsonObject ?? {}) as Map<String, dynamic>).map((key, value) => MapEntry(key, value?.toString() ?? ""));
}
return await _postForResponse(url, isFormData ? stringObj : requestBody,
token: token,
queryParameters: queryParameters,
headers: headers,
retryTimes: retryTimes);
return await _postForResponse(url, isFormData ? stringObj : requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes);
}
Future<Response> _postForResponse(String url, requestBody,
{String? token,
Map<String, dynamic>? queryParameters,
Map<String, String>? headers,
int retryTimes = 0}) async {
Future<Response> _postForResponse(String url, requestBody, {String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0}) async {
try {
var _headers = <String, String>{};
if (token != null) {
@ -164,9 +138,7 @@ class ApiClient {
var queryString = new Uri(queryParameters: queryParameters).query;
url = url + '?' + queryString;
}
var response =
await _post(Uri.parse(url), body: requestBody, headers: _headers)
.timeout(Duration(seconds: 120));
var response = await _post(Uri.parse(url), body: requestBody, headers: _headers).timeout(Duration(seconds: 120));
if (response.statusCode >= 200 && response.statusCode < 300) {
return response;
@ -177,11 +149,7 @@ class ApiClient {
if (retryTimes > 0) {
print('will retry after 3 seconds...');
await Future.delayed(Duration(seconds: 3));
return await _postForResponse(url, requestBody,
token: token,
queryParameters: queryParameters,
headers: headers,
retryTimes: retryTimes - 1);
return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1);
} else {
throw APIException(APIException.OTHER, arguments: e);
}
@ -189,11 +157,7 @@ class ApiClient {
if (retryTimes > 0) {
print('will retry after 3 seconds...');
await Future.delayed(Duration(seconds: 3));
return await _postForResponse(url, requestBody,
token: token,
queryParameters: queryParameters,
headers: headers,
retryTimes: retryTimes - 1);
return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1);
} else {
throw APIException(APIException.OTHER, arguments: e);
}
@ -203,39 +167,23 @@ class ApiClient {
if (retryTimes > 0) {
print('will retry after 3 seconds...');
await Future.delayed(Duration(seconds: 3));
return await _postForResponse(url, requestBody,
token: token,
queryParameters: queryParameters,
headers: headers,
retryTimes: retryTimes - 1);
return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1);
} else {
throw APIException(APIException.OTHER, arguments: e);
}
}
}
Future<Response> getJsonForResponse<T>(String url,
{String? token,
Map<String, dynamic>? queryParameters,
Map<String, String>? headers,
int retryTimes = 0}) async {
Future<Response> getJsonForResponse<T>(String url, {String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0}) async {
if (headers == null) {
headers = {'Content-Type': 'application/json'};
} else {
headers['Content-Type'] = 'application/json';
}
return await _getForResponse(url,
token: token,
queryParameters: queryParameters,
headers: headers,
retryTimes: retryTimes);
return await _getForResponse(url, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes);
}
Future<Response> _getForResponse(String url,
{String? token,
Map<String, dynamic>? queryParameters,
Map<String, String>? headers,
int retryTimes = 0}) async {
Future<Response> _getForResponse(String url, {String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0}) async {
try {
var _headers = <String, String>{};
if (token != null) {
@ -250,8 +198,7 @@ class ApiClient {
var queryString = new Uri(queryParameters: queryParameters).query;
url = url + '?' + queryString;
}
var response = await _get(Uri.parse(url), headers: _headers)
.timeout(Duration(seconds: 60));
var response = await _get(Uri.parse(url), headers: _headers).timeout(Duration(seconds: 60));
if (response.statusCode >= 200 && response.statusCode < 300) {
return response;
@ -262,11 +209,7 @@ class ApiClient {
if (retryTimes > 0) {
print('will retry after 3 seconds...');
await Future.delayed(Duration(seconds: 3));
return await _getForResponse(url,
token: token,
queryParameters: queryParameters,
headers: headers,
retryTimes: retryTimes - 1);
return await _getForResponse(url, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1);
} else {
throw APIException(APIException.OTHER, arguments: e);
}
@ -274,11 +217,7 @@ class ApiClient {
if (retryTimes > 0) {
print('will retry after 3 seconds...');
await Future.delayed(Duration(seconds: 3));
return await _getForResponse(url,
token: token,
queryParameters: queryParameters,
headers: headers,
retryTimes: retryTimes - 1);
return await _getForResponse(url, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1);
} else {
throw APIException(APIException.OTHER, arguments: e);
}
@ -288,19 +227,14 @@ class ApiClient {
if (retryTimes > 0) {
print('will retry after 3 seconds...');
await Future.delayed(Duration(seconds: 3));
return await _getForResponse(url,
token: token,
queryParameters: queryParameters,
headers: headers,
retryTimes: retryTimes - 1);
return await _getForResponse(url, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1);
} else {
throw APIException(APIException.OTHER, arguments: e);
}
}
}
Future<Response> _get(url, {Map<String, String>? headers}) =>
_withClient((client) => client.get(url, headers: headers));
Future<Response> _get(url, {Map<String, String>? headers}) => _withClient((client) => client.get(url, headers: headers));
bool _certificateCheck(X509Certificate cert, String host, int port) => true;
@ -314,8 +248,5 @@ class ApiClient {
}
}
Future<Response> _post(url,
{Map<String, String>? headers, body, Encoding? encoding}) =>
_withClient((client) =>
client.post(url, headers: headers, body: body, encoding: encoding));
Future<Response> _post(url, {Map<String, String>? headers, body, Encoding? encoding}) => _withClient((client) => client.post(url, headers: headers, body: body, encoding: encoding));
}

@ -0,0 +1,182 @@
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:http/http.dart';
import 'package:mohem_flutter_app/api/api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/exceptions/api_exception.dart';
import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart';
import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' as user;
import 'package:mohem_flutter_app/models/chat/make_user_favotire_unfavorite_chat_model.dart' as fav;
class ChatApiClient {
static final ChatApiClient _instance = ChatApiClient._internal();
ChatApiClient._internal();
factory ChatApiClient() => _instance;
Future<user.UserAutoLoginModel> getUserLoginToken() async {
Response response = await ApiClient().postJsonForResponse(
"${ApiConsts.chatLoginTokenUrl}externaluserlogin",
{
"employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(),
"password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG",
},
);
user.UserAutoLoginModel userLoginResponse = user.userAutoLoginModelFromJson(
response.body,
);
return userLoginResponse;
}
Future<List<ChatUser>?> getChatMemberFromSearch(String sName, int cUserId) async {
Response response = await ApiClient().getJsonForResponse(
"${ApiConsts.chatLoginTokenUrl}getUserWithStatusAndFavAsync/$sName/$cUserId",
token: AppState().chatDetails!.response!.token,
);
return searchUserJsonModel(response.body);
}
List<ChatUser> searchUserJsonModel(String str) => List<ChatUser>.from(
json.decode(str).map((x) => ChatUser.fromJson(x)),
);
Future<ChatUserModel> getRecentChats() async {
try {
Response response = await ApiClient().getJsonForResponse(
"${ApiConsts.chatRecentUrl}getchathistorybyuserid",
token: AppState().chatDetails!.response!.token,
);
return ChatUserModel.fromJson(
json.decode(response.body),
);
} catch (e) {
e as APIException;
if (e.message == "api_common_unauthorized") {
logger.d("Token Generated On APIIIIII");
user.UserAutoLoginModel userLoginResponse = await ChatApiClient().getUserLoginToken();
if (userLoginResponse.response != null) {
AppState().setchatUserDetails = userLoginResponse;
getRecentChats();
} else {
Utils.showToast(
userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr",
);
}
}
throw e;
}
}
Future<ChatUserModel> getFavUsers() async {
Response favRes = await ApiClient().getJsonForResponse(
"${ApiConsts.chatFavUser}getFavUserById/${AppState().chatDetails!.response!.id}",
token: AppState().chatDetails!.response!.token,
);
return ChatUserModel.fromJson(
json.decode(favRes.body),
);
}
Future<Response> getSingleUserChatHistory({required int senderUID, required int receiverUID, required bool loadMore, bool isNewChat = false, required int paginationVal}) async {
try {
Response response = await ApiClient().getJsonForResponse(
"${ApiConsts.chatSingleUserHistoryUrl}GetUserChatHistory/$senderUID/$receiverUID/$paginationVal",
token: AppState().chatDetails!.response!.token,
);
return response;
} catch (e) {
e as APIException;
if (e.message == "api_common_unauthorized") {
user.UserAutoLoginModel userLoginResponse = await ChatApiClient().getUserLoginToken();
if (userLoginResponse.response != null) {
AppState().setchatUserDetails = userLoginResponse;
getSingleUserChatHistory(senderUID: senderUID, receiverUID: receiverUID, loadMore: loadMore, paginationVal: paginationVal);
} else {
Utils.showToast(
userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr",
);
}
}
throw e;
}
}
Future<fav.FavoriteChatUser> favUser({required int userID, required int targetUserID}) async {
Response response = await ApiClient().postJsonForResponse(
"${ApiConsts.chatFavUser}addFavUser",
{
"targetUserId": targetUserID,
"userId": userID,
},
token: AppState().chatDetails!.response!.token);
fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body);
return favoriteChatUser;
}
Future<fav.FavoriteChatUser> unFavUser({required int userID, required int targetUserID}) async {
try {
Response response = await ApiClient().postJsonForResponse(
"${ApiConsts.chatFavUser}deleteFavUser",
{"targetUserId": targetUserID, "userId": userID},
token: AppState().chatDetails!.response!.token,
);
fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body);
return favoriteChatUser;
} catch (e) {
e as APIException;
if (e.message == "api_common_unauthorized") {
logger.d("Token Generated On APIIIIII");
user.UserAutoLoginModel userLoginResponse = await ChatApiClient().getUserLoginToken();
if (userLoginResponse.response != null) {
AppState().setchatUserDetails = userLoginResponse;
unFavUser(userID: userID, targetUserID: targetUserID);
} else {
Utils.showToast(
userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr",
);
}
}
throw e;
}
}
Future<StreamedResponse> uploadMedia(String userId, File file) async {
dynamic request = MultipartRequest('POST', Uri.parse('${ApiConsts.chatServerBaseApiUrl}upload'));
request.fields.addAll({'userId': userId, 'fileSource': '1'});
request.files.add(await MultipartFile.fromPath('files', file.path));
request.headers.addAll({'Authorization': 'Bearer ${AppState().chatDetails!.response!.token}'});
StreamedResponse response = await request.send();
return response;
}
// Download File For Chat
Future<Uint8List> downloadURL({required String fileName, required String fileTypeDescription}) async {
Response response = await ApiClient().postJsonForResponse(
"${ApiConsts.chatMediaImageUploadUrl}download",
{"fileType": fileTypeDescription, "fileName": fileName, "fileSource": 1},
token: AppState().chatDetails!.response!.token,
);
Uint8List data = Uint8List.fromList(response.bodyBytes);
return data;
}
Future getUsersImages({required List encryptedEmails}) async {
Response response = await ApiClient().postJsonForResponse(
"${ApiConsts.chatUserImages}images",
{
"encryptedEmails": ["/g8Rc+s6eEOdci41PwJuV5dX+gXe51G9OTHzb9ahcVlHCmVvNhxReirudF79+hdxVSkCnQ6wC5DBFV8xnJlC74X6157PxF7mNYrAYuHRgp4="],
"fromClient": true
},
token: AppState().chatDetails!.response!.token,
);
logger.d(response.body);
// Uint8List data = Uint8List.fromList(response.body);
}
}

@ -182,8 +182,22 @@ class DashboardApiClient {
Future<ChatUnreadCovnCountModel> getChatCount() async {
Response response = await ApiClient().getJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}user/unreadconversationcount/${AppState().getUserName}",
"${ApiConsts.chatLoginTokenUrl}unreadconversationcount/${AppState().getUserName}",
);
return chatUnreadCovnCountModelFromJson(response.body);
}
// Future setAdvertisementViewed(String masterID, int advertisementId) async {
// String url = "${ApiConsts.cocRest}Mohemm_ITG_UpdateAdvertisementAsViewed";
//
// Map<String, dynamic> postParams = {
// "ItgNotificationMasterId": masterID,
// "ItgAdvertisement": {"advertisementId": advertisementId, "acknowledgment": true} //Mobile Id
// };
// postParams.addAll(AppState().postParamsJson);
// return await ApiClient().postJsonForObject((json) {
// // ItgMainRes responseData = ItgMainRes.fromJson(json);
// return json;
// }, url, postParams);
// }
}

@ -17,6 +17,7 @@ class MyColors {
static const Color greyF7Color = Color(0xffF7F7F7);
static const Color grey80Color = Color(0xff808080);
static const Color grey70Color = Color(0xff707070);
static const Color grey7BColor = Color(0xff7B7B7B);
static const Color greyACColor = Color(0xffACACAC);
static const Color grey98Color = Color(0xff989898);
static const Color lightGreyEFColor = Color(0xffEFEFEF);

@ -12,29 +12,20 @@ class ApiConsts {
static String user = baseUrlServices + "api/User/";
static String cocRest = baseUrlServices + "COCWS.svc/REST/";
//Chat
static String chatServerBaseUrl = "https://apiderichat.hmg.com";
static String chatServerBaseApiUrl = "https://apiderichat.hmg.com/api/";
static String chatHubConnectionUrl = chatServerBaseUrl + "/ConnectionChatHub";
static String chatSearchMember = "user/getUserWithStatusAndFavAsync/";
static String chatRecentUrl = "UserChatHistory/getchathistorybyuserid"; //For a Mem
static String chatSingleUserHistoryUrl = "UserChatHistory/GetUserChatHistory";
static String chatMediaImageUploadUrl = "shared/upload";
static String chatFavoriteUsers = "FavUser/getFavUserById/";
// 42062 is CurrentUserID and 36745 is targetUserID and 0 is For Pagination
// static String chatSearchMember = "https://apiderichat.hmg.com/api/user/getUserWithStatusAndFavAsync/aamir.muhammad/36239";
// todo @aamir move api end point last repo to concerned method.
//Brain Marathon Constants
static String marathonBaseUrl = "https://18.188.181.12/service/";
static String marathonParticipantLoginUrl = marathonBaseUrl + "api/auth/participantlogin";
static String marathonProjectGetUrl = marathonBaseUrl + "api/Project/Project_Get";
static String marathonUpcomingUrl = marathonBaseUrl + "api/marathon/upcoming/";
static String marathonHubConnectionUrl = marathonBaseUrl + "MarathonBroadCast";
//DummyCards for the UI
//Chat
static String chatServerBaseUrl = "https://apiderichat.hmg.com/";
static String chatServerBaseApiUrl = chatServerBaseUrl + "api/";
static String chatLoginTokenUrl = chatServerBaseApiUrl + "user/";
static String chatHubConnectionUrl = chatServerBaseUrl + "ConnectionChatHub";
static CardContent dummyQuestion = const CardContent();
// static String chatSearchMember = chatLoginTokenUrl + "user/";
static String chatRecentUrl = chatServerBaseApiUrl + "UserChatHistory/"; //For a Mem
static String chatSingleUserHistoryUrl = chatServerBaseApiUrl + "UserChatHistory/";
static String chatMediaImageUploadUrl = chatServerBaseApiUrl + "shared/";
static String chatFavUser = chatServerBaseApiUrl + "FavUser/";
static String chatUserImages = chatServerBaseUrl + "empservice/api/employee/";
}
class SharedPrefsConsts {

@ -40,7 +40,7 @@ class DateUtil {
}
static DateTime convertSimpleStringDateToDate(String date) {
return DateFormat("MM/dd/yyyy hh:mm:ss").parse(date);
return DateFormat("MM/dd/yyyy hh:mm:ss a").parse(date);
}
static DateTime convertSimpleStringDateToDateddMMyyyy(String date) {

@ -7,6 +7,7 @@ import 'package:mohem_flutter_app/ui/chat/chat_detailed_screen.dart';
import 'package:mohem_flutter_app/ui/chat/chat_home.dart';
import 'package:mohem_flutter_app/ui/chat/favorite_users_screen.dart';
import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart';
import 'package:mohem_flutter_app/ui/landing/itg/its_add_screen_video_image.dart';
import 'package:mohem_flutter_app/ui/landing/itg/survey_screen.dart';
import 'package:mohem_flutter_app/ui/landing/today_attendance_screen.dart';
import 'package:mohem_flutter_app/ui/landing/today_attendance_screen2.dart';
@ -87,6 +88,7 @@ class AppRoutes {
static const String addEitScreen = "/addeitScreen";
static const String initialRoute = login;
static const String survey = "/survey";
static const String advertisement = "/advertisement";
//Work List
static const String workList = "/workList";
@ -116,8 +118,7 @@ class AppRoutes {
static const String addVacationRule = "/addVacationRule";
//Bottom Sheet
static const String attendanceDetailsBottomSheet =
"/attendanceDetailsBottomSheet";
static const String attendanceDetailsBottomSheet = "/attendanceDetailsBottomSheet";
//Profile
static const String profile = "/profile";
@ -135,8 +136,7 @@ class AppRoutes {
// Pending Transactions
static const String pendingTransactions = "/pendingTransactions";
static const String pendingTransactionsDetails =
"/pendingTransactionsDetails";
static const String pendingTransactionsDetails = "/pendingTransactionsDetails";
// Announcements
static const String announcements = "/announcements";
@ -192,6 +192,7 @@ class AppRoutes {
verifyLastLogin: (BuildContext context) => VerifyLastLoginScreen(),
dashboard: (BuildContext context) => DashboardScreen(),
survey: (BuildContext context) => SurveyScreen(),
advertisement: (BuildContext context) => ITGAdsScreen(),
subMenuScreen: (BuildContext context) => SubMenuScreen(),
newPassword: (BuildContext context) => NewPasswordScreen(),
@ -223,8 +224,7 @@ class AppRoutes {
addVacationRule: (BuildContext context) => AddVacationRuleScreen(),
//Bottom Sheet
attendanceDetailsBottomSheet: (BuildContext context) =>
AttendenceDetailsBottomSheet(),
attendanceDetailsBottomSheet: (BuildContext context) => AttendenceDetailsBottomSheet(),
//Profile
//profile: (BuildContext context) => Profile(),
@ -235,13 +235,10 @@ class AppRoutes {
familyMembers: (BuildContext context) => FamilyMembers(),
dynamicScreen: (BuildContext context) => DynamicListViewScreen(),
addDynamicInput: (BuildContext context) => DynamicInputScreen(),
addDynamicInputProfile: (BuildContext context) =>
DynamicInputScreenProfile(),
addDynamicAddressScreen: (BuildContext context) =>
DynamicInputScreenAddress(),
addDynamicInputProfile: (BuildContext context) => DynamicInputScreenProfile(),
addDynamicAddressScreen: (BuildContext context) => DynamicInputScreenAddress(),
deleteFamilyMember: (BuildContext context) =>
DeleteFamilyMember(ModalRoute.of(context)!.settings.arguments as int),
deleteFamilyMember: (BuildContext context) => DeleteFamilyMember(ModalRoute.of(context)!.settings.arguments as int),
requestSubmitScreen: (BuildContext context) => RequestSubmitScreen(),
addUpdateFamilyMember: (BuildContext context) => AddUpdateFamilyMember(),
@ -251,8 +248,7 @@ class AppRoutes {
mowadhafhiHRRequest: (BuildContext context) => MowadhafhiHRRequest(),
pendingTransactions: (BuildContext context) => PendingTransactions(),
pendingTransactionsDetails: (BuildContext context) =>
PendingTransactionsDetails(),
pendingTransactionsDetails: (BuildContext context) => PendingTransactionsDetails(),
announcements: (BuildContext context) => Announcements(),
announcementsDetails: (BuildContext context) => AnnouncementDetails(),
@ -268,8 +264,7 @@ class AppRoutes {
// Offers & Discounts
offersAndDiscounts: (BuildContext context) => OffersAndDiscountsHome(),
offersAndDiscountsDetails: (BuildContext context) =>
OffersAndDiscountsDetails(),
offersAndDiscountsDetails: (BuildContext context) => OffersAndDiscountsDetails(),
//pay slip
monthlyPaySlip: (BuildContext context) => MonthlyPaySlipScreen(),
@ -296,8 +291,7 @@ class AppRoutes {
// Marathon
marathonIntroScreen: (BuildContext context) => MarathonIntroScreen(),
marathonScreen: (BuildContext context) => MarathonScreen(),
marathonWinnerSelection: (BuildContext context) =>
MarathonWinnerSelection(),
marathonWinnerSelection: (BuildContext context) => MarathonWinnerSelection(),
marathonWinnerScreen: (BuildContext context) => WinnerScreen(),
};
}

@ -136,7 +136,7 @@ extension EmailValidator on String {
Widget toText21({Color? color, bool isBold = false, FontWeight? weight, int? maxlines}) => Text(
this,
maxLines: maxlines,
style: TextStyle(color: color ?? MyColors.grey3AColor, fontSize: 21, letterSpacing: -0.31, fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.w600)),
style: TextStyle(color: color ?? MyColors.grey3AColor, fontSize: 21, letterSpacing: -0.84, fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.w600)),
);
Widget toText22({Color? color, bool isBold = false}) => Text(
@ -149,6 +149,11 @@ extension EmailValidator on String {
style: TextStyle(height: 23 / 24, color: color ?? MyColors.darkTextColor, fontSize: 24, letterSpacing: -1.44, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
);
Widget toText30({Color? color, bool isBold = false}) => Text(
this,
style: TextStyle(height: 20 / 32, color: color ?? MyColors.darkTextColor, fontSize: 32, letterSpacing: -1.2, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
);
Widget toText32({Color? color, bool isBold = false}) => Text(
this,
style: TextStyle(height: 32 / 32, color: color ?? MyColors.darkTextColor, fontSize: 32, letterSpacing: -1.92, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),

@ -3,7 +3,7 @@ import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:logger/logger.dart';
import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/generated/codegen_loader.g.dart';

@ -7,7 +7,7 @@ import 'dart:convert';
class CallDataModel {
CallDataModel({
this.callerId,
this.callReciverId,
this.callReceiverID,
this.notificationForeground,
this.message,
this.title,
@ -27,7 +27,7 @@ class CallDataModel {
});
String? callerId;
String? callReciverId;
String? callReceiverID;
String? notificationForeground;
String? message;
String? title;
@ -51,7 +51,7 @@ class CallDataModel {
factory CallDataModel.fromJson(Map<String, dynamic> json) => CallDataModel(
callerId: json["callerID"] == null ? null : json["callerID"],
callReciverId: json["callReciverID"] == null ? null : json["callReciverID"],
callReceiverID: json["callReceiverID"] == null ? null : json["callReceiverID"],
notificationForeground: json["notification_foreground"] == null ? null : json["notification_foreground"],
message: json["message"] == null ? null : json["message"],
title: json["title"] == null ? null : json["title"],
@ -78,7 +78,7 @@ class CallDataModel {
Map<String, dynamic> toJson() => {
"callerID": callerId == null ? null : callerId,
"callReciverID": callReciverId == null ? null : callReciverId,
"callReceiverID": callReceiverID == null ? null : callReceiverID,
"notification_foreground": notificationForeground == null ? null : notificationForeground,
"message": message == null ? null : message,
"title": title == null ? null : title,

@ -19,21 +19,21 @@ class ChatUserModel {
}
class ChatUser {
ChatUser({
this.id,
this.userName,
this.email,
this.phone,
this.title,
this.userStatus,
this.image,
this.unreadMessageCount,
this.userAction,
this.isPin,
this.isFav,
this.isAdmin,
this.isTyping,
});
ChatUser(
{this.id,
this.userName,
this.email,
this.phone,
this.title,
this.userStatus,
this.image,
this.unreadMessageCount,
this.userAction,
this.isPin,
this.isFav,
this.isAdmin,
this.isTyping,
this.isLoadingCounter});
int? id;
String? userName;
@ -48,6 +48,7 @@ class ChatUser {
bool? isFav;
bool? isAdmin;
bool? isTyping;
bool? isLoadingCounter;
factory ChatUser.fromJson(Map<String, dynamic> json) => ChatUser(
id: json["id"] == null ? null : json["id"],
@ -63,6 +64,7 @@ class ChatUser {
isFav: json["isFav"] == null ? null : json["isFav"],
isAdmin: json["isAdmin"] == null ? null : json["isAdmin"],
isTyping: false,
isLoadingCounter: true,
);
Map<String, dynamic> toJson() => {

@ -1,21 +1,22 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart';
import 'package:logger/logger.dart' as L;
import 'package:logging/logging.dart';
import 'package:mohem_flutter_app/api/api_client.dart';
import 'package:mohem_flutter_app/api/chat/chat_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/exceptions/api_exception.dart';
import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/chat/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_login_token_model.dart' as login;
import 'package:mohem_flutter_app/models/chat/make_user_favotire_unfavorite_chat_model.dart' as fav;
import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart';
import 'package:mohem_flutter_app/widgets/image_picker.dart';
import 'package:signalr_netcore/signalr_client.dart';
import 'package:uuid/uuid.dart';
@ -26,9 +27,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
TextEditingController search = TextEditingController();
List<SingleUserChatModel> userChatHistory = [];
List<ChatUser>? pChatHistory, searchedChats;
late HubConnection hubConnection;
L.Logger logger = L.Logger();
bool hubConInitialized = false;
String chatCID = '';
bool isLoading = true;
bool isChatScreenActive = false;
@ -40,56 +38,20 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
List<ChatUser> favUsersList = [];
int paginationVal = 0;
Future<void> getUserAutoLoginToken(BuildContext cxt) async {
Response response = await ApiClient().postJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}user/externaluserlogin",
{
"employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(),
"password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG",
},
);
login.UserAutoLoginModel userLoginResponse = login.userAutoLoginModelFromJson(
response.body,
);
if (userLoginResponse.response != null) {
hubConInitialized = true;
AppState().setchatUserDetails = userLoginResponse;
await buildHubConnection();
} else {
Utils.showToast(
userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr",
);
return;
}
}
Future<List<ChatUser>?> getChatMemberFromSearch(String sName, int cUserId) async {
Response response = await ApiClient().getJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatSearchMember}$sName/$cUserId",
token: AppState().chatDetails!.response!.token,
);
return searchUserJsonModel(response.body);
void registerEvents() {
hubConnection.on("OnUpdateUserStatusAsync", changeStatus);
hubConnection.on("OnDeliveredChatUserAsync", onMsgReceived);
// hubConnection.on("OnSeenChatUserAsync", onChatSeen);
//hubConnection.on("OnUserTypingAsync", onUserTyping);
hubConnection.on("OnUserCountAsync", userCountAsync);
hubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow);
hubConnection.on("OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered);
hubConnection.on("OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus);
}
List<ChatUser> searchUserJsonModel(String str) => List<ChatUser>.from(
json.decode(str).map(
(x) => ChatUser.fromJson(x),
),
);
void getUserRecentChats() async {
Response response = await ApiClient().getJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatRecentUrl}",
token: AppState().chatDetails!.response!.token,
);
ChatUserModel recentChat = userToList(response.body);
Response favRes = await ApiClient().getJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatFavoriteUsers}${AppState().chatDetails!.response!.id}",
token: AppState().chatDetails!.response!.token,
);
ChatUserModel favUList = userToList(favRes.body);
ChatUserModel recentChat = await ChatApiClient().getRecentChats();
ChatUserModel favUList = await ChatApiClient().getFavUsers();
if (favUList.response != null && recentChat.response != null) {
favUsersList = favUList.response!;
@ -108,21 +70,20 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
pChatHistory = recentChat.response ?? [];
pChatHistory!.sort(
(ChatUser a, ChatUser b) => a.userName!.toLowerCase().compareTo(
b.userName!.toLowerCase(),
),
(ChatUser a, ChatUser b) => a.userName!.toLowerCase().compareTo(b.userName!.toLowerCase()),
);
searchedChats = pChatHistory;
isLoading = false;
await invokeUserChatHistoryNotDeliveredAsync(
userId: int.parse(
AppState().chatDetails!.response!.id.toString(),
),
);
notifyListeners();
}
Future getUserChatHistoryNotDeliveredAsync({required int userId}) async {
await hubConnection.invoke(
"GetUserChatHistoryNotDeliveredAsync",
args: [userId],
);
Future invokeUserChatHistoryNotDeliveredAsync({required int userId}) async {
await hubConnection.invoke("GetUserChatHistoryNotDeliveredAsync", args: [userId]);
return "";
}
@ -131,9 +92,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
if (isNewChat) userChatHistory = [];
if (!loadMore) paginationVal = 0;
isChatScreenActive = true;
Response response = await ApiClient().getJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatSingleUserHistoryUrl}/$senderUID/$receiverUID/$paginationVal",
token: AppState().chatDetails!.response!.token,
Response response = await ChatApiClient().getSingleUserChatHistory(
senderUID: senderUID,
receiverUID: receiverUID,
loadMore: loadMore,
paginationVal: paginationVal,
);
if (response.statusCode == 204) {
if (isNewChat) {
@ -156,9 +119,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
).reversed.toList();
}
}
await getUserChatHistoryNotDeliveredAsync(
userId: senderUID,
);
isLoading = false;
notifyListeners();
markRead(
@ -173,24 +133,28 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
chatCID = uuid.v4();
}
void markRead(List<SingleUserChatModel> data, reciverID) {
for (SingleUserChatModel element in data!) {
if (!element.isSeen!) {
dynamic data = [
{
"userChatHistoryId": element.userChatHistoryId,
"TargetUserId": element.targetUserId,
"isDelivered": true,
"isSeen": true,
void markRead(List<SingleUserChatModel> data, int receiverID) {
if (data != null) {
for (SingleUserChatModel element in data!) {
if (element.isSeen != null) {
if (!element.isSeen!) {
dynamic data = [
{
"userChatHistoryId": element.userChatHistoryId,
"TargetUserId": element.targetUserId,
"isDelivered": true,
"isSeen": true,
}
];
updateUserChatHistoryStatusAsync(data);
}
];
updateUserChatHistoryStatusAsync(data);
}
}
}
for (ChatUser element in searchedChats!) {
if (element.id == reciverID) {
element.unreadMessageCount = 0;
notifyListeners();
for (ChatUser element in searchedChats!) {
if (element.id == receiverID) {
element.unreadMessageCount = 0;
notifyListeners();
}
}
}
}
@ -208,27 +172,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
),
);
ChatUserModel userToList(String str) => ChatUserModel.fromJson(
json.decode(str),
);
Future<dynamic> uploadAttachments(String userId, File file) async {
dynamic result;
dynamic request = MultipartRequest(
'POST',
Uri.parse(
'${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatMediaImageUploadUrl}',
),
);
request.fields.addAll({'userId': userId, 'fileSource': '1'});
request.files.add(await MultipartFile.fromPath('files', file.path));
request.headers.addAll(
{
'Authorization': 'Bearer ${AppState().chatDetails!.response!.token}',
},
);
try {
StreamedResponse response = await request.send();
StreamedResponse response = await ChatApiClient().uploadMedia(userId, file);
if (response.statusCode == 200) {
result = jsonDecode(
await response.stream.bytesToString(),
@ -237,59 +184,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
result = [];
}
} catch (e) {
if (kDebugMode) {
print(e);
}
print(e);
}
;
return result;
}
Future<void> buildHubConnection() async {
HttpConnectionOptions httpOp = HttpConnectionOptions(
skipNegotiation: false,
logMessageContent: true,
);
hubConnection = HubConnectionBuilder()
.withUrl(
ApiConsts.chatHubConnectionUrl + "?UserId=${AppState().chatDetails!.response!.id}&source=Web&access_token=${AppState().chatDetails!.response!.token}",
options: httpOp,
)
.withAutomaticReconnect(
retryDelays: <int>[2000, 5000, 10000, 20000],
)
.configureLogging(
Logger("Loggin"),
)
.build();
hubConnection.onclose(
({Exception? error}) {},
);
hubConnection.onreconnecting(
({Exception? error}) {},
);
hubConnection.onreconnected(
({String? connectionId}) {},
);
if (hubConnection.state != HubConnectionState.Connected) {
await hubConnection.start();
getUserChatHistoryNotDeliveredAsync(
userId: int.parse(
AppState().chatDetails!.response!.id.toString(),
),
);
hubConnection.on("OnUpdateUserStatusAsync", changeStatus);
hubConnection.on("OnDeliveredChatUserAsync", onMsgReceived);
// hubConnection.on("OnSeenChatUserAsync", onChatSeen);
//hubConnection.on("OnUserTypingAsync", onUserTyping);
hubConnection.on("OnUserCountAsync", userCountAsync);
hubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow);
hubConnection.on("OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered);
hubConnection.on("OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus);
}
}
void updateUserChatStatus(List<Object?>? args) {
dynamic items = args!.toList();
for (dynamic cItem in items[0]) {
@ -342,32 +242,23 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
void chatNotDelivered(List<Object?>? args) {
dynamic items = args!.toList();
logger.d(items);
for (dynamic item in items[0]) {
searchedChats!.forEach((element) {
if (element.id == item["currentUserId"]) {
var val = element.unreadMessageCount == null ? 0 : element.unreadMessageCount;
element.unreadMessageCount = val! + 1;
}
});
// dynamic data = [
// {
// "userChatHistoryId": item["userChatHistoryId"],
// "TargetUserId": item["targetUserId"],
// "isDelivered": true,
// "isSeen": true,
// }
// ];
// updateUserChatHistoryStatusAsync(data);
searchedChats!.forEach(
(ChatUser element) {
if (element.id == item["currentUserId"]) {
int? val = element.unreadMessageCount ?? 0;
element.unreadMessageCount = val! + 1;
}
element.isLoadingCounter = false;
},
);
}
notifyListeners();
}
void changeStatus(List<Object?>? args) {
if (kDebugMode) {
// print("================= Status Online // Offline ====================");
}
dynamic items = args!.toList();
// logger.d(items);
for (ChatUser user in searchedChats!) {
if (user.id == items.first["id"]) {
user.userStatus = items.first["userStatus"];
@ -403,13 +294,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
data.first.currentUserName = temp.first.targetUserName;
}
userChatHistory.insert(0, data.first);
// searchedChats!.forEach((element) {
// if (element.id == data.first.currentUserId) {
// var val = element.unreadMessageCount == null ? 0 : element.unreadMessageCount;
// element.unreadMessageCount = val! + 1;
// }
// });
var list = [
{
"userChatHistoryId": data.first.userChatHistoryId,
@ -419,14 +303,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
];
updateUserChatHistoryStatusAsync(list);
notifyListeners();
// if (isChatScreenActive) scrollToBottom();
}
void onUserTyping(List<Object?>? parameters) {
// print("==================== Typing Active ==================");
// logger.d(parameters);
for (ChatUser user in searchedChats!) {
if (user.id == parameters![1] && parameters[0] == true) {
user.isTyping = parameters[0] as bool?;
@ -556,12 +436,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
ChatUser(
id: targetUserId,
userName: targetUserName,
unreadMessageCount: 0
),
);
notifyListeners();
}
if (!isFileSelected && !isMsgReply) {
logger.d("Normal Text Message");
if (message.text == null || message.text.isEmpty) {
return;
}
@ -569,14 +449,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
if (isFileSelected && !isMsgReply) {
Utils.showLoading(context);
//logger.d("Normal Attachment Message");
dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile);
String? ext = getFileExtension(selectedFile.path);
Utils.hideLoading(context);
sendChatToServer(chatEventId: 2, fileTypeId: getFileType(ext.toString()), targetUserId: targetUserId, targetUserName: targetUserName, isAttachment: true, chatReplyId: null, isReply: false);
}
if (!isFileSelected && isMsgReply) {
// logger.d("Normal Text Message With Reply");
if (message.text == null || message.text.isEmpty) {
return;
}
@ -584,7 +462,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
chatEventId: 1, fileTypeId: null, targetUserId: targetUserId, targetUserName: targetUserName, chatReplyId: repliedMsg.first.userChatHistoryId, isAttachment: false, isReply: true);
}
if (isFileSelected && isMsgReply) {
// logger.d("Attachment Message With Reply");
Utils.showLoading(context);
dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile);
String? ext = getFileExtension(selectedFile.path);
@ -697,9 +574,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
Future<void> favoriteUser({required int userID, required int targetUserID}) async {
Response response =
await ApiClient().postJsonForResponse("${ApiConsts.chatServerBaseApiUrl}FavUser/addFavUser", {"targetUserId": targetUserID, "userId": userID}, token: AppState().chatDetails!.response!.token);
fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body);
fav.FavoriteChatUser favoriteChatUser = await ChatApiClient().favUser(userID: userID, targetUserID: targetUserID);
if (favoriteChatUser.response != null) {
for (ChatUser user in searchedChats!) {
if (user.id == favoriteChatUser.response!.targetUserId!) {
@ -712,21 +587,24 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
Future<void> unFavoriteUser({required int userID, required int targetUserID}) async {
Response response = await ApiClient()
.postJsonForResponse("${ApiConsts.chatServerBaseApiUrl}FavUser/deleteFavUser", {"targetUserId": targetUserID, "userId": userID}, token: AppState().chatDetails!.response!.token);
fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body);
fav.FavoriteChatUser favoriteChatUser = await ChatApiClient().unFavUser(userID: userID, targetUserID: targetUserID);
if (favoriteChatUser.response != null) {
for (var user in searchedChats!) {
for (ChatUser user in searchedChats!) {
if (user.id == favoriteChatUser.response!.targetUserId!) {
user.isFav = favoriteChatUser.response!.isFav;
}
}
favUsersList.removeWhere((ChatUser element) => element.id == targetUserID);
favUsersList.removeWhere(
(ChatUser element) => element.id == targetUserID,
);
}
notifyListeners();
}
void clearSelections() {
print("Hereee i am ");
searchedChats = pChatHistory;
search.clear();
isChatScreenActive = false;
@ -735,6 +613,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
isFileSelected = false;
repliedMsg = [];
sFileType = "";
isMsgReply = false;
notifyListeners();
}
@ -773,4 +652,26 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
curve: Curves.easeIn,
);
}
// Future<void> getDownLoadFile(String fileName) async {
// var data = await ChatApiClient().downloadURL(fileName: "data");
// Image.memory(data);
// }
// void getUserChatHistoryNotDeliveredAsync({required int userId}) async {
// try {
// await hubConnection.invoke("GetUserChatHistoryNotDeliveredAsync", args: [userId]);
// } finally {
// hubConnection.off("GetUserChatHistoryNotDeliveredAsync", method: chatNotDelivered);
// }
// }
}

@ -1,13 +1,17 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/chat/chat_api_client.dart';
import 'package:mohem_flutter_app/api/dashboard_api_client.dart';
import 'package:mohem_flutter_app/api/offers_and_discounts_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/chat/chat_count_conversation_model.dart';
import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart';
import 'package:mohem_flutter_app/models/dashboard/drawer_menu_item_model.dart';
import 'package:mohem_flutter_app/models/dashboard/get_accrual_balances_list_model.dart';
import 'package:mohem_flutter_app/models/dashboard/get_attendance_tracking_list_model.dart';
@ -21,6 +25,7 @@ import 'package:mohem_flutter_app/models/generic_response_model.dart';
import 'package:mohem_flutter_app/models/itg/itg_response_model.dart';
import 'package:mohem_flutter_app/models/offers_and_discounts/get_offers_list.dart';
import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart';
import 'package:signalr_netcore/signalr_client.dart';
/// Mix-in [DiagnosticableTreeMixin] to have access to [debugFillProperties] for the devtool
// ignore: prefer_mixin
@ -37,6 +42,7 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
//Chat
bool isChatCounterLoding = true;
bool isChatHubLoding = true;
int chatUConvCounter = 0;
//Misssing Swipe
@ -97,6 +103,7 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
leaveBalanceAccrual = null;
isChatCounterLoding = true;
isChatHubLoding = true;
chatUConvCounter = 0;
ticketBalance = 0;
@ -287,6 +294,26 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
}
Future<void> getUserAutoLoginToken() async {
UserAutoLoginModel userLoginResponse = await ChatApiClient().getUserLoginToken();
if (userLoginResponse.response != null) {
AppState().setchatUserDetails = userLoginResponse;
} else {
Utils.showToast(
userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr",
);
}
}
Future<HubConnection> getHubConnection() async {
HubConnection hub;
HttpConnectionOptions httpOp = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true);
hub = HubConnectionBuilder()
.withUrl(ApiConsts.chatHubConnectionUrl + "?UserId=${AppState().chatDetails!.response!.id}&source=Web&access_token=${AppState().chatDetails!.response!.token}", options: httpOp)
.withAutomaticReconnect(retryDelays: <int>[2000, 5000, 10000, 20000]).build();
isChatHubLoding = false;
return hub;
}
void notify() {
notifyListeners();
}

@ -316,7 +316,7 @@ class _AddVacationRuleScreenState extends State<AddVacationRuleScreen> {
12.height,
PopupMenuButton(
child: DynamicTextFieldWidget(
"Notification",
LocaleKeys.notification.tr(),
selectedItemTypeNotification == null ? LocaleKeys.selectNotification.tr() : selectedItemTypeNotification!.nOTIFICATIONDISPLAYNAME!,
isEnable: false,
isPopup: true,

@ -91,6 +91,8 @@ class _IncomingCallState extends State<IncomingCall> with SingleTickerProviderSt
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: const <Widget>[
// todo @aamir, need to use extension mehtods
Text(
"Aamir Saleem Ahmad",
style: TextStyle(

@ -1,9 +1,15 @@
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/api_client.dart';
import 'package:mohem_flutter_app/api/chat/chat_api_client.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:sizer/sizer.dart';
import 'package:mohem_flutter_app/main.dart';
// todo: @aamir use extension methods, and use correct widgets.
class ChatBubble extends StatelessWidget {
const ChatBubble(
@ -15,7 +21,9 @@ class ChatBubble extends StatelessWidget {
required this.isDelivered,
required this.dateTime,
required this.isReplied,
required this.userName})
required this.userName,
this.fileTypeID,
this.fileTypeDescription})
: super(key: key);
final String text;
final String replyText;
@ -25,9 +33,13 @@ class ChatBubble extends StatelessWidget {
final String dateTime;
final bool isReplied;
final String userName;
final int? fileTypeID;
final String? fileTypeDescription;
@override
Widget build(BuildContext context) {
return isCurrentUser ? currentUser(context) : receiptUser(context);
return Padding(
// padding: EdgeInsets.zero,
padding: EdgeInsets.only(
@ -132,12 +144,12 @@ class ChatBubble extends StatelessWidget {
color: isCurrentUser ? MyColors.grey41Color.withOpacity(.5) : MyColors.white.withOpacity(0.7),
),
if (isCurrentUser) 5.width,
// if (isCurrentUser)
// Icon(
// isDelivered ? Icons.done_all : Icons.done_all,
// color: isSeen ? MyColors.textMixColor : MyColors.grey9DColor,
// size: 14,
// ),
if (isCurrentUser)
Icon(
isDelivered ? Icons.done_all : Icons.done_all,
color: isSeen ? MyColors.textMixColor : MyColors.grey9DColor,
size: 14,
),
],
),
],
@ -147,4 +159,125 @@ class ChatBubble extends StatelessWidget {
),
);
}
Widget currentUser(context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (isReplied)
ClipRRect(
borderRadius: BorderRadius.circular(
5.0,
),
child: Container(
width: double.infinity,
decoration: BoxDecoration(
border: Border(
left: BorderSide(width: 6, color: isCurrentUser ? MyColors.gradiantStartColor : MyColors.white),
),
color: isCurrentUser ? MyColors.black.withOpacity(0.10) : MyColors.black.withOpacity(0.30),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
(userName).toText12(color: MyColors.gradiantStartColor, isBold: false).paddingOnly(right: 5, top: 5, bottom: 0, left: 5),
replyText.toText10(color: isCurrentUser ? MyColors.grey71Color : MyColors.white.withOpacity(0.5), isBold: false, maxlines: 4).paddingOnly(right: 5, top: 5, bottom: 8, left: 5),
],
).expanded,
),
).paddingOnly(right: 5, bottom: 7),
if (fileTypeID == 12 || fileTypeID == 4 || fileTypeID == 3) showImage().paddingOnly(right: 5),
if (fileTypeID != 12 || fileTypeID != 4 || fileTypeID != 3) (text).toText12(),
Align(
alignment: Alignment.centerRight,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
dateTime.toText10(color: MyColors.grey41Color.withOpacity(.5)),
7.width,
Icon(
isDelivered ? Icons.done_all : Icons.done_all,
color: isSeen ? MyColors.textMixColor : MyColors.grey9DColor,
size: 14,
),
],
),
),
],
).paddingOnly(top: 11, left: 13, right: 7, bottom: 5).objectContainerView(disablePadding: true).paddingOnly(left: MediaQuery.of(context).size.width * 0.3);
}
Widget receiptUser(context) {
return Container(
padding: const EdgeInsets.only(top: 11, left: 13, right: 7, bottom: 5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
gradient: const LinearGradient(
transform: GradientRotation(.83),
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: <Color>[
MyColors.gradiantEndColor,
MyColors.gradiantStartColor,
],
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (isReplied)
ClipRRect(
borderRadius: BorderRadius.circular(
5.0,
),
child: Container(
width: double.infinity,
decoration: BoxDecoration(
border: Border(
left: BorderSide(width: 6, color: isCurrentUser ? MyColors.gradiantStartColor : MyColors.white),
),
color: isCurrentUser ? MyColors.black.withOpacity(0.10) : MyColors.black.withOpacity(0.30),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
(userName).toText12(color: MyColors.gradiantStartColor, isBold: false).paddingOnly(right: 5, top: 5, bottom: 0, left: 5),
replyText.toText10(color: isCurrentUser ? MyColors.grey71Color : MyColors.white.withOpacity(0.5), isBold: false, maxlines: 4).paddingOnly(right: 5, top: 5, bottom: 8, left: 5),
],
).expanded,
),
).paddingOnly(right: 5, bottom: 7),
if (fileTypeID == 12 || fileTypeID == 4 || fileTypeID == 3) showImage().paddingOnly(right: 5) else (text).toText12(color: Colors.white),
Align(
alignment: Alignment.centerRight,
child: dateTime.toText10(
color: Colors.white.withOpacity(.71),
),
),
],
),
).paddingOnly(right: MediaQuery.of(context).size.width * 0.3);
}
Widget showImage() {
return FutureBuilder<Uint8List>(
future: ChatApiClient().downloadURL(fileName: text, fileTypeDescription: fileTypeDescription!),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.connectionState != ConnectionState.waiting) {
if (snapshot.data == null) {
return (text).toText12(color: Colors.white);
} else {
return Image.memory(
snapshot.data,
height: 140,
width: 227,
fit: BoxFit.cover,
);
}
} else {
return const SizedBox(height: 140, width: 227, child: Center(child: CircularProgressIndicator()));
}
},
);
}
}

@ -4,7 +4,6 @@ import 'dart:convert';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
@ -13,13 +12,16 @@ import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/chat/call.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/ui/chat/call/chat_outgoing_call_screen.dart';
import 'package:mohem_flutter_app/ui/chat/chat_bubble.dart';
import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart';
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart';
import 'package:provider/provider.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:signalr_netcore/signalr_client.dart';
import 'package:sizer/sizer.dart';
import 'package:swipe_to/swipe_to.dart';
class ChatDetailScreen extends StatefulWidget {
@ -38,18 +40,17 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
void getMoreChat() async {
if (userDetails != null) {
data.paginationVal = data.paginationVal + 10;
if (userDetails != null)
if (userDetails != null) {
data.getSingleUserChatHistory(
senderUID: AppState().chatDetails!.response!.id!.toInt(),
receiverUID: userDetails["targetUser"].id,
loadMore: true,
isNewChat: false,
);
}
}
await Future.delayed(
const Duration(
milliseconds: 1000,
),
const Duration(milliseconds: 1000),
);
_rc.loadComplete();
}
@ -68,284 +69,152 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
}
return Scaffold(
backgroundColor: const Color(0xFFF8F8F8),
appBar: AppBarWidget(context,
title: userDetails["targetUser"].userName.toString().replaceAll(".", " ").capitalizeFirstofEach,
showHomeButton: false,
image: userDetails["targetUser"].image,
actions: [
IconButton(
onPressed: () {
// makeCall(
// callType: "AUDIO",
// con: data.hubConnection,
// );
},
icon: SvgPicture.asset(
"assets/icons/chat/call.svg",
width: 22,
height: 22,
),
),
IconButton(
onPressed: () {
// makeCall(
// callType: "VIDEO",
// con: data.hubConnection,
// );
},
icon: SvgPicture.asset(
"assets/icons/chat/video_call.svg",
width: 20,
height: 20,
),
),
10.width,
]),
backgroundColor: MyColors.backgroundColor,
appBar: AppBarWidget(
context,
title: userDetails["targetUser"].userName.toString().replaceAll(".", " ").capitalizeFirstofEach,
showHomeButton: false,
image: userDetails["targetUser"].image,
actions: [
SvgPicture.asset("assets/icons/chat/call.svg", width: 21, height: 23).onPress(() {
// makeCall(callType: "AUDIO", con: hubConnection);
}),
24.width,
SvgPicture.asset("assets/icons/chat/video_call.svg", width: 21, height: 18).onPress(() {
// makeCall(callType: "VIDEO", con: hubConnection);
}),
21.width,
],
),
body: Consumer<ChatProviderModel>(
builder: (BuildContext context, ChatProviderModel m, Widget? child) {
return (m.isLoading
? ChatHomeShimmer()
: Column(
children: <Widget>[
Expanded(
flex: 2,
child: SmartRefresher(
enablePullDown: false,
enablePullUp: true,
onLoading: () {
getMoreChat();
},
header: const MaterialClassicHeader(
color: MyColors.gradiantEndColor,
),
controller: _rc,
SmartRefresher(
enablePullDown: false,
enablePullUp: true,
onLoading: () {
getMoreChat();
},
header: const MaterialClassicHeader(
color: MyColors.gradiantEndColor,
),
controller: _rc,
reverse: true,
child: ListView.separated(
controller: m.scrollController,
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
reverse: true,
child: ListView.builder(
controller: m.scrollController,
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
reverse: true,
itemCount: m.userChatHistory.length,
padding: const EdgeInsets.only(top: 20),
itemBuilder: (BuildContext context, int i) {
return SwipeTo(
iconColor: MyColors.lightGreenColor,
child: ChatBubble(
text: m.userChatHistory[i].contant.toString(),
replyText: m.userChatHistory[i].userChatReplyResponse != null ? m.userChatHistory[i].userChatReplyResponse!.contant.toString() : "",
isSeen: m.userChatHistory[i].isSeen == true ? true : false,
isCurrentUser: m.userChatHistory[i].currentUserId == AppState().chatDetails!.response!.id ? true : false,
isDelivered: m.userChatHistory[i].currentUserId == AppState().chatDetails!.response!.id && m.userChatHistory[i].isDelivered == true ? true : false,
dateTime: m.dateFormte(m.userChatHistory[i].createdDate!),
isReplied: m.userChatHistory[i].userChatReplyResponse != null ? true : false,
userName: AppState().chatDetails!.response!.userName == m.userChatHistory[i].currentUserName.toString() ? "You" : m.userChatHistory[i].currentUserName.toString(),
),
onRightSwipe: () {
m.chatReply(
m.userChatHistory[i],
);
},
);
},
),
itemCount: m.userChatHistory.length,
padding: const EdgeInsets.all(21),
separatorBuilder: (cxt, index) => 8.height,
itemBuilder: (BuildContext context, int i) {
return SwipeTo(
iconColor: MyColors.lightGreenColor,
child: ChatBubble(
text: m.userChatHistory[i].contant.toString(),
replyText: m.userChatHistory[i].userChatReplyResponse != null ? m.userChatHistory[i].userChatReplyResponse!.contant.toString() : "",
isSeen: m.userChatHistory[i].isSeen == true ? true : false,
isCurrentUser: m.userChatHistory[i].currentUserId == AppState().chatDetails!.response!.id ? true : false,
isDelivered: m.userChatHistory[i].currentUserId == AppState().chatDetails!.response!.id && m.userChatHistory[i].isDelivered == true ? true : false,
dateTime: m.dateFormte(m.userChatHistory[i].createdDate!),
isReplied: m.userChatHistory[i].userChatReplyResponse != null ? true : false,
userName: AppState().chatDetails!.response!.userName == m.userChatHistory[i].currentUserName.toString() ? "You" : m.userChatHistory[i].currentUserName.toString(),
fileTypeID: m.userChatHistory[i].fileTypeId,
fileTypeDescription: m.userChatHistory[i].fileTypeResponse!.fileTypeDescription,
),
onRightSwipe: () {
m.chatReply(
m.userChatHistory[i],
);
},
).onPress(() {
logger.d(jsonEncode(m.userChatHistory[i]));
});
},
),
),
).expanded,
if (m.isMsgReply)
Row(
children: <Widget>[
Container(
height: 80,
color: MyColors.textMixColor,
width: 6,
),
Expanded(
child: Container(
height: 80,
color: MyColors.black.withOpacity(0.10),
child: ListTile(
title: (AppState().chatDetails!.response!.userName == m.repliedMsg.first.currentUserName.toString()
? "You"
: m.repliedMsg.first.currentUserName.toString().replaceAll(".", " "))
.toText14(color: MyColors.lightGreenColor),
subtitle: (m.repliedMsg.isNotEmpty ? m.repliedMsg.first.contant! : "").toText12(
color: MyColors.white,
maxLine: 2,
),
trailing: GestureDetector(
onTap: m.closeMe,
child: Container(
decoration: BoxDecoration(
color: MyColors.white.withOpacity(0.5),
borderRadius: const BorderRadius.all(
Radius.circular(20),
),
),
child: const Icon(
Icons.close,
size: 23,
color: MyColors.white,
),
),
),
SizedBox(
height: 82,
child: Row(
children: <Widget>[
Container(height: 82, color: MyColors.textMixColor, width: 6),
Container(
color: MyColors.darkTextColor.withOpacity(0.10),
padding: const EdgeInsets.only(top: 11, left: 14, bottom: 14, right: 21),
child: Row(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(AppState().chatDetails!.response!.userName == m.repliedMsg.first.currentUserName.toString()
? "You"
: m.repliedMsg.first.currentUserName.toString().replaceAll(".", " "))
.toText14(color: MyColors.lightGreenColor),
(m.repliedMsg.isNotEmpty ? m.repliedMsg.first.contant! : "").toText12(color: MyColors.grey71Color, maxLine: 2)
],
).expanded,
12.width,
const Icon(Icons.cancel, size: 23, color: MyColors.grey7BColor).onPress(m.closeMe),
],
),
),
),
],
).expanded,
],
),
),
if (m.isFileSelected && m.sFileType == ".png" || m.sFileType == ".jpeg" || m.sFileType == ".jpg")
Card(
margin: EdgeInsets.zero,
elevation: 0,
child: Padding(
padding: const EdgeInsets.only(
left: 20,
right: 20,
top: 20,
bottom: 0,
),
child: Card(
margin: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
elevation: 0,
child: Container(
height: 200,
decoration: BoxDecoration(
image: DecorationImage(
image: FileImage(
m.selectedFile,
),
fit: BoxFit.cover,
),
borderRadius: const BorderRadius.all(
Radius.circular(0),
),
),
child: const SizedBox(
width: double.infinity,
height: 200,
),
),
),
SizedBox(height: 200, width: double.infinity, child: Image.file(m.selectedFile, fit: BoxFit.cover)).paddingOnly(left: 21, right: 21, top: 21),
TextField(
controller: m.message,
decoration: InputDecoration(
hintText: m.isFileSelected ? m.selectedFile.path.split("/").last : LocaleKeys.typeheretoreply.tr(),
hintStyle: TextStyle(color: m.isFileSelected ? MyColors.darkTextColor : MyColors.grey98Color, fontSize: 14),
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
filled: true,
fillColor: MyColors.white,
contentPadding: const EdgeInsets.only(
left: 21,
top: 20,
bottom: 20,
),
),
Card(
margin: EdgeInsets.zero,
child: TextField(
controller: m.message,
decoration: InputDecoration(
hintText: m.isFileSelected ? m.selectedFile.path.split("/").last : LocaleKeys.typeheretoreply.tr(),
hintStyle: TextStyle(
color: m.isFileSelected ? MyColors.darkTextColor : MyColors.grey98Color,
fontSize: 14,
),
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding: EdgeInsets.only(
left: m.sFileType.isNotEmpty ? 10 : 20,
right: m.sFileType.isNotEmpty ? 0 : 5,
top: 20,
bottom: 20,
),
prefixIcon: m.sFileType.isNotEmpty
? Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
prefixIconConstraints: const BoxConstraints(),
prefixIcon: m.sFileType.isNotEmpty
? SvgPicture.asset(m.getType(m.sFileType), height: 30, width: 22, alignment: Alignment.center, fit: BoxFit.cover).paddingOnly(left: 21, right: 15)
: null,
suffixIcon: SizedBox(
width: 100,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center, // added line
children: <Widget>[
if (m.sFileType.isNotEmpty)
Row(
children: <Widget>[
SvgPicture.asset(
m.getType(m.sFileType),
height: 30,
width: 25,
alignment: Alignment.center,
fit: BoxFit.cover,
).paddingOnly(left: 20),
const Icon(Icons.cancel, size: 15, color: MyColors.redA3Color).paddingOnly(right: 5),
("Clear").toText11(color: MyColors.redA3Color, isUnderLine: true).paddingOnly(left: 0),
],
)
: null,
suffixIcon: SizedBox(
width: 96,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center, // added line
children: <Widget>[
if (m.sFileType.isNotEmpty)
IconButton(
padding: EdgeInsets.zero,
alignment: Alignment.centerRight,
icon: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
decoration: const BoxDecoration(
color: MyColors.redA3Color,
borderRadius: BorderRadius.all(
Radius.circular(20),
),
),
child: const Icon(
Icons.close,
size: 15,
color: MyColors.white,
),
),
("Clear")
.toText11(
color: MyColors.redA3Color,
)
.paddingOnly(
left: 4,
),
],
),
onPressed: () async {
m.removeAttachment();
},
),
if (m.sFileType.isEmpty)
RotationTransition(
turns: const AlwaysStoppedAnimation(45 / 360),
child: IconButton(
padding: EdgeInsets.zero,
alignment: Alignment.topRight,
icon: const Icon(
Icons.attach_file_rounded,
size: 26,
color: MyColors.grey3AColor,
),
onPressed: () async {
m.selectImageToUpload(context);
},
),
).onPress(() => m.removeAttachment()).paddingOnly(right: 25),
if (m.sFileType.isEmpty)
RotationTransition(
turns: const AlwaysStoppedAnimation(45 / 360),
child: const Icon(Icons.attach_file_rounded, size: 26, color: MyColors.grey3AColor).onPress(
() => m.selectImageToUpload(context),
),
IconButton(
alignment: Alignment.centerRight,
padding: EdgeInsets.zero,
icon: SvgPicture.asset(
"assets/icons/chat/chat_send_icon.svg",
height: 26,
width: 26,
),
onPressed: () {
m.sendChatMessage(
userDetails["targetUser"].id,
userDetails["targetUser"].userName,
context,
);
},
)
],
),
).paddingOnly(
right: 20,
).paddingOnly(right: 25),
SvgPicture.asset("assets/icons/chat/chat_send_icon.svg", height: 26, width: 26).onPress(
() => m.sendChatMessage(userDetails["targetUser"].id, userDetails["targetUser"].userName, context),
),
],
),
),
).paddingOnly(right: 21),
),
),
],
@ -357,38 +226,41 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
void makeCall({required String callType, required HubConnection con}) async {
print("================== Make call Triggered ============================");
logger.d(jsonEncode(AppState().chatDetails!.response));
Map<String, dynamic> json = {
"callerID": AppState().chatDetails!.response!.id!.toString(),
"callReciverID": userDetails["targetUser"].id.toString(),
"callReceiverID": userDetails["targetUser"].id.toString(),
"notification_foreground": "true",
"message": "Aamir is calling ",
"message": "Aamir is calling",
"title": "Video Call",
"type": callType == "VIDEO" ? "Video" : "Audio",
"identity": "Aamir.Muhammad",
"name": "Aamir Saleem Ahmad",
"identity": AppState().chatDetails!.response!.userName,
"name": AppState().chatDetails!.response!.title,
"is_call": "true",
"is_webrtc": "true",
"contant": "Start video Call Aamir.Muhammad",
"contant": "Start video Call ${AppState().chatDetails!.response!.userName}",
"contantNo": "775d1f11-62d9-6fcc-91f6-21f8c14559fb",
"chatEventId": "3",
"fileTypeId": null,
"currentUserId": "266642",
"currentUserId": AppState().chatDetails!.response!.id!.toString(),
"chatSource": "1",
"userChatHistoryLineRequestList": [
{"isSeen": false, "isDelivered": false, "targetUserId": 341682, "targetUserStatus": 4}
{
"isSeen": false,
"isDelivered": false,
"targetUserId": userDetails["targetUser"].id,
"targetUserStatus": 4,
}
],
// "server": "https://192.168.8.163:8086",
"server": "https://livecareturn.hmg.com:8086",
};
CallDataModel incomingCallData = CallDataModel.fromJson(json);
CallDataModel callData = CallDataModel.fromJson(json);
await Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => OutGoingCall(
isVideoCall: callType == "VIDEO" ? true : false,
OutGoingCallData: incomingCallData,
OutGoingCallData: callData,
),
),
);

@ -1,19 +1,13 @@
import 'dart:convert';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/chat/chat_provider_model.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/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/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/screens/items_for_sale/fragments/items_for_sale.dart';
import 'package:mohem_flutter_app/ui/screens/items_for_sale/fragments/my_posted_ads_fragment.dart';
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
import 'package:provider/provider.dart';
@ -31,32 +25,21 @@ class _ChatHomeState extends State<ChatHome> {
@override
void initState() {
// TODO: implement initState
super.initState();
data = Provider.of<ChatProviderModel>(context, listen: false);
data.getUserAutoLoginToken(context).whenComplete(() {
data.getUserRecentChats();
});
}
@override
void dispose() {
super.dispose();
data.clearAll();
if (data.hubConInitialized) {
data.hubConnection.stop();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: MyColors.white,
appBar: AppBarWidget(
context,
title: LocaleKeys.chat.tr(),
showHomeButton: true,
),
appBar: AppBarWidget(context, title: LocaleKeys.chat.tr(), showHomeButton: true),
body: Column(
children: <Widget>[
Container(

@ -2,13 +2,13 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/api/chat/chat_provider_model.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/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';
@ -21,6 +21,16 @@ class ChatHomeScreen extends StatefulWidget {
class _ChatHomeScreenState extends State<ChatHomeScreen> {
TextEditingController search = TextEditingController();
late ChatProviderModel data;
@override
void initState() {
// TODO: implement initState
super.initState();
data = Provider.of<ChatProviderModel>(context, listen: false);
data.registerEvents();
data.getUserRecentChats();
}
@override
void dispose() {
@ -36,110 +46,87 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
builder: (BuildContext context, ChatProviderModel m, Widget? child) {
return m.isLoading
? ChatHomeShimmer()
: ListView(
shrinkWrap: true,
physics: const AlwaysScrollableScrollPhysics(),
: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(
vertical: 20,
horizontal: 20,
),
child: TextField(
controller: m.search,
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.symmetric(
horizontal: 15,
vertical: 10,
),
hintText: LocaleKeys.searchfromchat.tr(),
hintStyle: const TextStyle(
color: MyColors.lightTextColor,
fontStyle: FontStyle.italic,
),
filled: true,
fillColor: const Color(
0xFFF7F7F7,
),
suffixIcon: m.search.text.isNotEmpty
? IconButton(
onPressed: () {
m.clearSelections();
},
icon: const Icon(
Icons.clear,
size: 22,
),
color: MyColors.redA3Color,
)
: null,
),
TextField(
controller: m.search,
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.searchfromchat.tr(),
hintStyle: const TextStyle(color: MyColors.lightTextColor, fontStyle: FontStyle.italic, fontWeight: FontWeight.w500, fontSize: 12),
filled: true,
fillColor: const Color(0xFFF7F7F7),
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.searchedChats != null)
ListView.separated(
itemCount: m.searchedChats!.length,
padding: const EdgeInsets.only(
bottom: 80,
),
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
physics: const ClampingScrollPhysics(),
itemBuilder: (BuildContext context, int index) {
// todo @aamir, remove list tile, make a custom ui instead
return SizedBox(
height: 55,
child: ListTile(
leading: Stack(
children: <Widget>[
SvgPicture.asset(
"assets/images/user.svg",
height: 48,
width: 48,
),
Positioned(
right: 5,
bottom: 1,
child: Container(
width: 10,
height: 10,
decoration: BoxDecoration(
color: m.searchedChats![index].userStatus == 1 ? MyColors.green2DColor : Colors.red,
borderRadius: const BorderRadius.all(
Radius.circular(10),
child: Row(
children: [
Stack(
children: <Widget>[
SvgPicture.asset(
"assets/images/user.svg",
height: 48,
width: 48,
),
Positioned(
right: 5,
bottom: 1,
child: Container(
width: 10,
height: 10,
decoration: BoxDecoration(
color: m.searchedChats![index].userStatus == 1 ? MyColors.green2DColor : Colors.red,
borderRadius: const BorderRadius.all(
Radius.circular(10),
),
),
),
),
)
],
),
title: (m.searchedChats![index].userName!.replaceFirst(".", " ").capitalizeFirstofEach ?? "").toText14(color: MyColors.darkTextColor),
// subtitle: (m.searchedChats![index].isTyping == true ? "Typing ..." : "").toText11(color: MyColors.normalTextColor),
trailing: SizedBox(
width: 60,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
if (m.searchedChats![index].unreadMessageCount! > 0)
Flexible(
child: Container(
padding: EdgeInsets.zero,
alignment: Alignment.centerRight,
)
],
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(m.searchedChats![index].userName!.replaceFirst(".", " ").capitalizeFirstofEach ?? "").toText14(color: MyColors.darkTextColor).paddingOnly(left: 11, top: 13),
],
).expanded,
SizedBox(
width: 60,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
if (m.searchedChats![index].unreadMessageCount! > 0)
Container(
alignment: Alignment.center,
width: 18,
height: 18,
decoration: const BoxDecoration(
@ -153,17 +140,12 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
color: MyColors.white,
)
.center,
),
),
Flexible(
child: IconButton(
alignment: Alignment.centerRight,
padding: EdgeInsets.zero,
icon: Icon(
m.searchedChats![index].isFav != null && m.searchedChats![index].isFav == false ? Icons.star_sharp : Icons.star_sharp,
),
).paddingOnly(right: 10).center,
Icon(
m.searchedChats![index].isFav != null && m.searchedChats![index].isFav == false ? Icons.star_sharp : Icons.star_sharp,
color: m.searchedChats![index].isFav != null && m.searchedChats![index].isFav == true ? MyColors.yellowColor : MyColors.grey35Color,
onPressed: () {
).onPress(
() {
if (m.searchedChats![index].isFav == null || m.searchedChats![index].isFav == false) {
m.favoriteUser(
userID: AppState().chatDetails!.response!.id!,
@ -181,40 +163,28 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
);
}
},
),
)
],
).center
],
),
),
),
minVerticalPadding: 0,
onTap: () {
Navigator.pushNamed(
context,
AppRoutes.chatDetailed,
arguments: {"targetUser": m.searchedChats![index], "isNewChat": false},
).then((Object? value) {
// m.GetUserChatHistoryNotDeliveredAsync(userId: int.parse(AppState().chatDetails!.response!.id.toString()));
m.clearSelections();
m.notifyListeners();
});
},
],
),
);
).onPress(() {
Navigator.pushNamed(
context,
AppRoutes.chatDetailed,
arguments: {"targetUser": m.searchedChats![index], "isNewChat": false},
).then((Object? value) {
// m.GetUserChatHistoryNotDeliveredAsync(userId: int.parse(AppState().chatDetails!.response!.id.toString()));
m.clearSelections();
m.notifyListeners();
});
});
},
separatorBuilder: (BuildContext context, int index) => const Padding(
padding: EdgeInsets.only(
right: 10,
left: 70,
),
child: Divider(
color: Color(
0xFFE5E5E5,
),
),
),
),
separatorBuilder: (BuildContext context, int index) => const Divider(color: MyColors.lightGreyE5Color).paddingOnly(left: 59),
).paddingOnly(bottom: 70).expanded,
],
);
).paddingOnly(left: 21, right: 21);
},
),
floatingActionButton: FloatingActionButton(

@ -1,7 +1,8 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart';
import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
@ -26,81 +27,80 @@ class ChatFavoriteUsersScreen extends StatelessWidget {
return m.favUsersList != null && m.favUsersList.isNotEmpty
? ListView.separated(
itemCount: m.favUsersList!.length,
padding: const EdgeInsets.only(top: 20),
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int index) {
return SizedBox(
height: 55,
child: ListTile(
leading: Stack(
children: <Widget>[
SvgPicture.asset(
"assets/images/user.svg",
height: 48,
width: 48,
),
Positioned(
right: 5,
bottom: 1,
child: Container(
width: 10,
height: 10,
decoration: BoxDecoration(
color: m.favUsersList![index].userStatus == 1 ? MyColors.green2DColor : Colors.red,
borderRadius: const BorderRadius.all(
Radius.circular(10),
child: Row(
children: [
Stack(
children: <Widget>[
SvgPicture.asset(
"assets/images/user.svg",
height: 48,
width: 48,
),
Positioned(
right: 5,
bottom: 1,
child: Container(
width: 10,
height: 10,
decoration: BoxDecoration(
color: m.favUsersList![index].userStatus == 1 ? MyColors.green2DColor : Colors.red,
borderRadius: const BorderRadius.all(
Radius.circular(10),
),
),
),
),
)
],
),
title: (m.favUsersList![index].userName!.replaceFirst(".", " ").capitalizeFirstofEach ?? "").toText14(
color: MyColors.darkTextColor,
),
trailing: IconButton(
alignment: Alignment.centerRight,
padding: EdgeInsets.zero,
icon: Icon(
m.favUsersList![index].isFav! ? Icons.star : Icons.star_border,
)
],
),
color: m.favUsersList![index].isFav! ? MyColors.yellowColor : MyColors.grey35Color,
onPressed: () {
if (m.favUsersList![index].isFav!)
m.unFavoriteUser(
userID: AppState().chatDetails!.response!.id!,
targetUserID: m.favUsersList![index].id!,
);
},
),
minVerticalPadding: 0,
onTap: () {
Navigator.pushNamed(
context,
AppRoutes.chatDetailed,
arguments: {"targetUser": m.favUsersList![index], "isNewChat": false},
).then(
(Object? value) {
m.clearSelections();
},
);
},
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(m.favUsersList![index].userName!.replaceFirst(".", " ").capitalizeFirstofEach ?? "").toText14(color: MyColors.darkTextColor).paddingOnly(left: 11, top: 13),
],
).expanded,
SizedBox(
width: 60,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Icon(
m.favUsersList![index].isFav! ? Icons.star : Icons.star_border,
color: m.favUsersList![index].isFav! ? MyColors.yellowColor : MyColors.grey35Color,
).onPress(() {
if (m.favUsersList![index].isFav!) {
m.unFavoriteUser(
userID: AppState().chatDetails!.response!.id!,
targetUserID: m.favUsersList![index].id!,
);
}
}).center,
],
),
),
],
),
);
).onPress(() {
Navigator.pushNamed(
context,
AppRoutes.chatDetailed,
arguments: {"targetUser": m.favUsersList![index], "isNewChat": false},
).then(
(Object? value) {
m.clearSelections();
},
);
});
},
separatorBuilder: (BuildContext context, int index) => const Padding(
padding: EdgeInsets.only(
right: 10,
left: 70,
),
child: Divider(
color: Color(
0xFFE5E5E5,
),
),
),
)
separatorBuilder: (BuildContext context, int index) => const Divider(color: MyColors.lightGreyE5Color).paddingOnly(left: 70),
).paddingAll(21)
: Column(
children: <Widget>[
Utils.getNoDataWidget(context).expanded,

@ -1,12 +1,15 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_countdown_timer/flutter_countdown_timer.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/api/dashboard_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
@ -15,6 +18,7 @@ import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/models/offers_and_discounts/get_offers_list.dart';
import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart';
import 'package:mohem_flutter_app/ui/landing/itg/its_add_screen_video_image.dart';
import 'package:mohem_flutter_app/ui/landing/widget/app_drawer.dart';
import 'package:mohem_flutter_app/ui/landing/widget/menus_widget.dart';
import 'package:mohem_flutter_app/ui/landing/widget/services_widget.dart';
@ -26,6 +30,9 @@ import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'
import 'package:mohem_flutter_app/widgets/shimmer/offers_shimmer_widget.dart';
import 'package:provider/provider.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:signalr_netcore/signalr_client.dart';
late HubConnection hubConnection;
class DashboardScreen extends StatefulWidget {
DashboardScreen({Key? key}) : super(key: key);
@ -51,13 +58,26 @@ class _DashboardScreenState extends State<DashboardScreen> {
scheduleMicrotask(() {
data = Provider.of<DashboardProviderModel>(context, listen: false);
marathonProvider = Provider.of<MarathonProvider>(context, listen: false);
_bHubCon();
_onRefresh();
});
}
void buildHubConnection() async {
hubConnection = await data.getHubConnection();
await hubConnection.start();
}
@override
void dispose() {
super.dispose();
hubConnection.stop();
}
void _bHubCon() {
data.getUserAutoLoginToken().whenComplete(() {
buildHubConnection();
});
}
void _onRefresh() async {
@ -87,29 +107,29 @@ class _DashboardScreenState extends State<DashboardScreen> {
// actions: [
// IconButton(
// onPressed: () {
// data.getITGNotification().then((value) {
// print("--------------------detail_1-----------------");
// if (value!.result!.data != null) {
// print(value.result!.data!.notificationMasterId);
// print(value.result!.data!.notificationType);
// if (value.result!.data!.notificationType == "Survey") {
// Navigator.pushNamed(context, AppRoutes.survey, arguments: value.result!.data);
// data.getITGNotification().then((val) {
// if (val!.result!.data != null) {
// if (val.result!.data!.notificationType == "Survey") {
// Navigator.pushNamed(context, AppRoutes.survey, arguments: val.result!.data);
// } else {
// DashboardApiClient().getAdvertisementDetail(value.result!.data!.notificationMasterId ?? "").then(
// DashboardApiClient().getAdvertisementDetail(val.result!.data!.notificationMasterId ?? "").then(
// (value) {
// if (value!.mohemmItgResponseItem!.statusCode == 200) {
// if (value.mohemmItgResponseItem!.result!.data != null) {
// String? image64 = value.mohemmItgResponseItem!.result!.data!.advertisement!.viewAttachFileColl!.first.base64String;
// print(image64);
// var sp = image64!.split("base64,");
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => MovieTheaterBody(
// encodedBytes: sp[1],
// ),
// ),
// );
// Navigator.pushNamed(context, AppRoutes.advertisement, arguments: {
// "masterId": val.result!.data!.notificationMasterId,
// "advertisement": value.mohemmItgResponseItem!.result!.data!.advertisement,
// });
//
// // Navigator.push(
// // context,
// // MaterialPageRoute(
// // builder: (BuildContext context) => ITGAdsScreen(
// // addMasterId: val.result!.data!.notificationMasterId!,
// // advertisement: value.mohemmItgResponseItem!.result!.data!.advertisement!,
// // ),
// // ),
// // );
// }
// }
// },

@ -0,0 +1,135 @@
import 'dart:convert';
import 'dart:io' as Io;
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:just_audio/just_audio.dart';
import 'package:mohem_flutter_app/api/dashboard_api_client.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/itg/advertisement.dart' as ads;
import 'package:path_provider/path_provider.dart';
import 'package:video_player/video_player.dart';
class ITGAdsScreen extends StatefulWidget {
const ITGAdsScreen({Key? key}) : super(key: key);
@override
_ITGAdsScreenState createState() => _ITGAdsScreenState();
}
class _ITGAdsScreenState extends State<ITGAdsScreen> {
late Future<VideoPlayerController> _futureController;
late VideoPlayerController _controller;
bool skip = false;
bool isVideo = false;
bool isImage = false;
String ext = '';
late File imageFile;
ads.Advertisement? advertisementData;
dynamic data;
String? masterID;
void checkFileType() async {
String? rFile = advertisementData!.viewAttachFileColl!.first.base64String;
String? rFileExt = advertisementData!.viewAttachFileColl!.first.fileName;
ext = "." + rFileExt!.split(".").last.toLowerCase();
if (ext == ".png" || ext == ".jpg" || ext == ".jpeg" || ext == ".gif") {
await processImage(rFile!);
isImage = true;
} else {
isVideo = true;
_futureController = createVideoPlayer(rFile!);
}
setState(() {});
initTimer();
}
Future processImage(String encodedBytes) async {
try {
Uint8List decodedBytes = base64Decode(encodedBytes.split("base64,").last);
Directory appDocumentsDirectory = await getApplicationDocumentsDirectory(); // 1
imageFile = Io.File("${appDocumentsDirectory.path}/addImage$ext");
imageFile.writeAsBytesSync(decodedBytes);
} catch (e) {
logger.d(e);
}
}
Future<VideoPlayerController> createVideoPlayer(String encodedBytes) async {
try {
Uint8List decodedBytes = base64Decode(encodedBytes.split("base64,").last);
Directory appDocumentsDirectory = await getApplicationDocumentsDirectory(); // 1
File file = Io.File("${appDocumentsDirectory.path}/myAdsVideo.mp4");
file.writeAsBytesSync(decodedBytes);
VideoPlayerController controller = VideoPlayerController.file(file);
await controller.initialize();
await controller.play();
await controller.setVolume(1.0);
await controller.setLooping(false);
return controller;
} catch (e) {
return new VideoPlayerController.asset("dataSource");
}
}
void initTimer() {
Future.delayed(const Duration(seconds: 5), () {
skip = true;
setState(() {});
});
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
data = ModalRoute.of(context)!.settings.arguments;
if (advertisementData == null) advertisementData = data["advertisement"] as ads.Advertisement;
if (masterID == null) masterID = data["masterId"];
if (advertisementData != null) {
checkFileType();
}
double height = MediaQuery.of(context).size.height * .25;
return Scaffold(
body: Column(
children: [
if (isVideo)
SizedBox(
height: MediaQuery.of(context).size.height * .3,
child: FutureBuilder(
future: _futureController,
builder: (BuildContext context, AsyncSnapshot<Object?> snapshot) {
if (snapshot.connectionState == ConnectionState.done && snapshot.data != null) {
_controller = snapshot.data as VideoPlayerController;
return AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
},
),
),
if (isImage) Image.file(imageFile),
if (skip)
ElevatedButton(
onPressed: () async {
// DashboardApiClient().setAdvertisementViewed(widget.addMasterId, widget.advertisement!.advertisementId!).then((value) {
// logger.d(value);
// });
},
child: const Text("Go To Dashboard"),
)
],
),
);
}
}

@ -1,96 +0,0 @@
import 'dart:convert';
import 'dart:io' as Io;
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
class MovieTheaterBody extends StatefulWidget {
final String encodedBytes;
const MovieTheaterBody({required this.encodedBytes});
@override
_MovieTheaterBodyState createState() => _MovieTheaterBodyState();
}
class _MovieTheaterBodyState extends State<MovieTheaterBody> {
late Future<VideoPlayerController> _futureController;
late VideoPlayerController _controller;
Future<VideoPlayerController> createVideoPlayer() async {
try {
var decodedBytes = base64Decode(widget.encodedBytes);
var file = Io.File("decodedBezkoder.mp4");
file.writeAsBytesSync(decodedBytes);
VideoPlayerController controller = VideoPlayerController.file(file);
await controller.initialize();
await controller.setLooping(true);
return controller;
} catch (e) {
print("object0000000");
print(e);
return new VideoPlayerController.asset("dataSource");
}
}
@override
void initState() {
_futureController = createVideoPlayer();
super.initState();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Expanded(
child: FutureBuilder(
future: _futureController,
builder: (context, snapshot) {
//UST: 05/2021 - MovieTheaterBody - id:11 - 2pts - Criação
if (snapshot.connectionState == ConnectionState.done && snapshot.data != null) {
_controller = snapshot.data as VideoPlayerController;
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
),
const SizedBox(
height: 50,
),
FloatingActionButton(
onPressed: () {
setState(() {
if (_controller.value.isPlaying) {
_controller.pause();
} else {
// If the video is paused, play it.
_controller.play();
}
});
},
backgroundColor: Colors.green[700],
child: Icon(
_controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
),
)
],
);
} else {
return const Center(child: CircularProgressIndicator());
}
},
),
),
);
}
}

@ -128,6 +128,7 @@ class _LoginScreenState extends State<LoginScreen> {
Navigator.pushNamed(context, AppRoutes.verifyLogin,
arguments: "$firebaseToken");
}
Utils.saveStringFromPrefs(SharedPrefsConsts.password, password.text);
} catch (ex) {
Utils.hideLoading(context);
Utils.handleException(ex, context, (msg) {

@ -26,26 +26,18 @@ class MarathonIntroScreen extends StatelessWidget {
MarathonProvider provider = context.watch<MarathonProvider>();
return Scaffold(
appBar: AppBarWidget(context, title: LocaleKeys.brainMarathon.tr()),
body: Stack(
body: Column(
children: <Widget>[
SingleChildScrollView(
child: Column(
children: <Widget>[
MarathonDetailsCard(provider: provider).paddingAll(15),
MarathonTimerCard(
provider: provider,
timeToMarathon: DateTime.parse(provider.marathonDetailModel.startTime!).millisecondsSinceEpoch,
).paddingOnly(left: 15, right: 15, bottom: 15),
const SizedBox(
height: 100,
),
],
),
),
Align(
alignment: Alignment.bottomCenter,
child: MarathonFooter(provider: provider),
),
ListView(
padding: const EdgeInsets.all(21),
children: <Widget>[
MarathonDetailsCard(provider: provider),
10.height,
MarathonTimerCard(provider: provider, timeToMarathon: DateTime.parse(provider.marathonDetailModel.startTime!).millisecondsSinceEpoch,),
],
).expanded,
1.divider,
MarathonFooter(provider: provider),
],
),
);
@ -62,7 +54,7 @@ class MarathonDetailsCard extends StatelessWidget {
return Container(
width: double.infinity,
decoration: MyDecorations.shadowDecoration,
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 20),
padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 14),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
@ -136,7 +128,7 @@ class MarathonTimerCard extends StatelessWidget {
return Container(
width: double.infinity,
decoration: MyDecorations.shadowDecoration,
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 20),
padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 14),
child: Column(
children: <Widget>[
Row(
@ -151,15 +143,8 @@ class MarathonTimerCard extends StatelessWidget {
DateUtil.formatDateToTimeLang(DateTime.parse(provider.marathonDetailModel.startTime!), AppState().isArabic(context)).toText16(color: MyColors.darkTextColor, isBold: true),
],
),
Lottie.asset(
MyLottieConsts.hourGlassLottie,
height: 200,
),
BuildCountdownTimer(
timeToMarathon: timeToMarathon,
provider: provider,
screenFlag: 1,
),
Lottie.asset(MyLottieConsts.hourGlassLottie, height: 200),
BuildCountdownTimer(timeToMarathon: timeToMarathon, provider: provider, screenFlag: 1),
],
),
);
@ -180,38 +165,19 @@ class MarathonFooter extends StatelessWidget {
children: <InlineSpan>[
TextSpan(
text: LocaleKeys.note.tr(),
style: const TextStyle(
color: MyColors.darkTextColor,
fontSize: 17,
letterSpacing: -0.64,
fontWeight: FontWeight.bold,
),
style: const TextStyle(color: MyColors.darkTextColor, fontSize: 17, letterSpacing: -0.64, fontWeight: FontWeight.bold),
),
TextSpan(
text: " " + LocaleKeys.demoMarathonNoteP1.tr(),
style: const TextStyle(
color: MyColors.grey77Color,
fontSize: 17,
letterSpacing: -0.64,
fontWeight: FontWeight.w500,
),
style: const TextStyle(color: MyColors.grey77Color, fontSize: 17, letterSpacing: -0.64, fontWeight: FontWeight.w500),
),
TextSpan(
text: " " + LocaleKeys.demoMarathonNoteP2.tr(),
style: const TextStyle(
color: MyColors.darkTextColor,
fontSize: 17,
fontWeight: FontWeight.bold,
),
style: const TextStyle(color: MyColors.darkTextColor, fontSize: 17, fontWeight: FontWeight.bold),
),
TextSpan(
text: " " + LocaleKeys.demoMarathonNoteP3.tr(),
style: const TextStyle(
color: MyColors.grey77Color,
fontSize: 17,
letterSpacing: -0.64,
fontWeight: FontWeight.w500,
),
style: const TextStyle(color: MyColors.grey77Color, fontSize: 17, letterSpacing: -0.64, fontWeight: FontWeight.w500),
)
],
),

@ -16,8 +16,6 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart';
import 'package:mohem_flutter_app/ui/marathon/widgets/question_card_builder.dart';
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
import 'package:provider/provider.dart';
import 'package:sizer/sizer.dart';
import 'package:steps_indicator/steps_indicator.dart';
class MarathonScreen extends StatelessWidget {
const MarathonScreen({Key? key}) : super(key: key);
@ -103,7 +101,7 @@ class _MarathonProgressContainerState extends State<MarathonProgressContainer> {
return Container(
width: double.infinity,
decoration: MyDecorations.shadowDecoration,
padding: const EdgeInsets.all(21),
padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 13),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
@ -111,10 +109,7 @@ class _MarathonProgressContainerState extends State<MarathonProgressContainer> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
decoration: BoxDecoration(
color: MyColors.greenColor,
borderRadius: BorderRadius.circular(5),
),
decoration: BoxDecoration(color: MyColors.greenColor, borderRadius: BorderRadius.circular(5)),
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 8),
child: "${widget.provider.currentQuestionNumber.toString()} / ${widget.provider.marathonDetailModel.totalQuestions.toString()} ${LocaleKeys.question.tr()}"
.toText12(color: MyColors.white),
@ -124,38 +119,52 @@ class _MarathonProgressContainerState extends State<MarathonProgressContainer> {
.toText18(color: widget.provider.currentQuestionTime < 5 ? MyColors.redColor : MyColors.black),
],
),
15.height,
StepsIndicator(
lineLength: SizerUtil.deviceType == DeviceType.tablet ? MediaQuery.of(context).size.width * 0.077 : MediaQuery.of(context).size.width * 0.054,
nbSteps: 10,
selectedStep: widget.provider.currentQuestionNumber,
doneLineColor: MyColors.greenColor,
doneStepColor: MyColors.greenColor,
doneLineThickness: 6,
undoneLineThickness: 6,
selectedStepSize: 10,
unselectedStepSize: 10,
doneStepSize: 10,
selectedStepBorderSize: 0,
unselectedStepBorderSize: 0,
selectedStepColorIn: MyColors.greenColor,
selectedStepColorOut: MyColors.greenColor,
unselectedStepColorIn: MyColors.lightGreyDeColor,
unselectedStepColorOut: MyColors.lightGreyDeColor,
undoneLineColor: MyColors.lightGreyDeColor,
enableLineAnimation: false,
enableStepAnimation: false,
),
12.height,
stepper(widget.provider.currentQuestionNumber),
8.height,
Row(
children: <Widget>[
"${((widget.provider.currentQuestionNumber / widget.provider.marathonDetailModel.totalQuestions!) * 100).toInt()}% ${LocaleKeys.completed.tr()}".toText14(isBold: true),
"${((widget.provider.currentQuestionNumber / widget.provider.marathonDetailModel.totalQuestions!) * 100).toInt()}% ${LocaleKeys.completed.tr()}".toText14(),
],
),
],
),
);
}
Widget stepper(int value) {
return SizedBox(
width: double.infinity,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
for (int i = 0; i < 10; i++)
if (value <= i) roundContainer(MyColors.lightGreyDeColor, i != 0) else roundContainer(MyColors.greenColor, i != 0)
],
),
);
}
Widget roundContainer(Color color, bool isNeedLeftBorder) {
if (isNeedLeftBorder) {
return Row(
children: [
Divider(thickness: 6, color: color).expanded,
Container(
width: 10,
height: 10,
decoration: BoxDecoration(shape: BoxShape.circle, color: color),
),
],
).expanded;
}
return Container(
width: 10,
height: 10,
decoration: BoxDecoration(shape: BoxShape.circle, color: color),
);
}
}
// InkWell(

@ -29,7 +29,7 @@ class MarathonWinnerSelection extends StatelessWidget {
children: [
20.height,
QualifiersContainer(provider: provider).paddingOnly(left: 21, right: 21),
20.height,
12.height,
InkWell(
onTap: () {
Navigator.pushNamed(context, AppRoutes.marathonWinnerScreen);
@ -52,8 +52,8 @@ class MarathonWinnerSelection extends StatelessWidget {
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
"Muhammad Shrouff".toText18(isBold: true, color: MyColors.white),
"837436".toText18(isBold: true, color: MyColors.white),
"Muhammad Shrouff".toText17(isBold: true, color: MyColors.white),
"837436".toText17(isBold: true, color: MyColors.white),
],
),
),
@ -67,10 +67,10 @@ class MarathonWinnerSelection extends StatelessWidget {
title: Text(
LocaleKeys.fingersCrossed.tr(),
style: const TextStyle(
height: 23 / 24,
height: 27 / 27,
color: MyColors.greenColor,
fontSize: 27,
letterSpacing: -1,
letterSpacing: -1.08,
fontWeight: FontWeight.w600,
),
),
@ -78,9 +78,9 @@ class MarathonWinnerSelection extends StatelessWidget {
LocaleKeys.winnerSelectedRandomly.tr(),
textAlign: TextAlign.center,
style: const TextStyle(
color: MyColors.grey77Color,
fontSize: 16,
letterSpacing: -0.64,
color: MyColors.darkTextColor,
fontSize: 18,
letterSpacing: -0.72,
fontWeight: FontWeight.w600,
),
)).paddingOnly(left: 21, right: 21, top: 20, bottom: 20),
@ -124,22 +124,22 @@ class _QualifiersContainerState extends State<QualifiersContainer> {
return Container(
width: double.infinity,
decoration: MyDecorations.shadowDecoration,
padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 20),
padding: const EdgeInsets.only(top: 14,left: 18,right: 14,bottom: 18),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
LocaleKeys.winnerSelection.tr().toText18(isBold: true, color: MyColors.grey3AColor),
// "00:${widget.provider.start < 10 ? "0${widget.provider.start}" : widget.provider.start}".toText18(isBold: true, color: MyColors.redColor),
LocaleKeys.winnerSelection.tr().toText21(color: MyColors.grey3AColor),
// "00:${widget.provider.start < 10 ? "0${widget.provider.start}" : widget.provider.start}".toText18(color: MyColors.redColor),
],
),
10.height,
Row(
children: [
"18 ".toText32(color: MyColors.greenColor),
LocaleKeys.qualifiers.tr().toText20(color: MyColors.greenColor),
"18".toText30(color: MyColors.greenColor, isBold: true),2.width,
LocaleKeys.qualifiers.tr().toText16(color: MyColors.greenColor),
],
),
],

@ -60,6 +60,7 @@ class BuildCountdownTimer extends StatelessWidget {
children: <Widget>[
Column(
children: <Widget>[
// todo @faiz: Make a separate method and pass string , so we can minimize code replication
AutoSizeText(
"00",
maxFontSize: 24,
@ -155,6 +156,7 @@ class BuildCountdownTimer extends StatelessWidget {
children: <Widget>[
Column(
children: <Widget>[
// todo @faiz: Make a separate method and pass value and string , so we can minimize code replication
time.days == null
? AutoSizeText(
"00",

@ -112,7 +112,7 @@ class AnswerContent extends StatelessWidget {
Widget build(BuildContext context) {
MarathonProvider provider = context.watch<MarathonProvider>();
return Container(
padding: const EdgeInsets.all(13),
padding: const EdgeInsets.symmetric(vertical: 31, horizontal: 13),
decoration: const BoxDecoration(
color: MyColors.kWhiteColor,
borderRadius: BorderRadius.only(

@ -147,15 +147,15 @@ class ActionsFragment extends StatelessWidget {
if (actionHistoryList[index].aCTIONCODE == "SUBMIT") {
return "";
} else if (actionHistoryList[index].aCTIONCODE == "PENDING") {
if (actionHistoryList[++index].nOTIFICATIONDATE!.isEmpty) {
if (actionHistoryList[index + 1].nOTIFICATIONDATE!.isEmpty) {
return "";
}
DateTime dateTimeFrom = DateUtil.convertSimpleStringDateToDate(actionHistoryList[++index].nOTIFICATIONDATE!);
DateTime dateTimeFrom = DateUtil.convertSimpleStringDateToDate(actionHistoryList[index + 1].nOTIFICATIONDATE!);
Duration duration = DateTime.now().difference(dateTimeFrom);
return "Action duration: " + DateUtil.formatDuration(duration);
} else {
DateTime dateTimeTo = DateUtil.convertSimpleStringDateToDate(actionHistoryList[index].nOTIFICATIONDATE!);
DateTime dateTimeFrom = DateUtil.convertSimpleStringDateToDate(actionHistoryList[++index].nOTIFICATIONDATE!);
DateTime dateTimeFrom = DateUtil.convertSimpleStringDateToDate(actionHistoryList[index + 1].nOTIFICATIONDATE!);
Duration duration = dateTimeTo.difference(dateTimeFrom);
return "Action duration: " + DateUtil.formatDuration(duration);
}

@ -5,7 +5,7 @@ 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/api/chat/chat_provider_model.dart';
import 'package:mohem_flutter_app/api/chat/chat_api_client.dart';
import 'package:mohem_flutter_app/api/worklist/worklist_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
@ -88,7 +88,12 @@ class _SearchEmployeeBottomSheetState extends State<SearchEmployeeBottomSheet> {
void fetchChatUser({bool isNeedLoading = true}) async {
try {
Utils.showLoading(context);
chatUsersList = await ChatProviderModel().getChatMemberFromSearch(searchText, int.parse(AppState().chatDetails!.response!.id.toString()));
chatUsersList = await ChatApiClient().getChatMemberFromSearch(
searchText,
int.parse(
AppState().chatDetails!.response!.id.toString(),
),
);
Utils.hideLoading(context);
setState(() {});
} catch (e) {
@ -236,7 +241,6 @@ class _SearchEmployeeBottomSheetState extends State<SearchEmployeeBottomSheet> {
arguments: {"targetUser": chatUsersList![index], "isNewChat": true},
);
},
),
);
},

@ -20,7 +20,7 @@ class ImageOptions {
if (Platform.isAndroid) {
cameraImageAndroid(image);
} else {
File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.camera, imageQuality: 20))?.path ?? "");
File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.camera, imageQuality: 10))?.path ?? "");
String fileName = _image.path;
var bytes = File(fileName).readAsBytesSync();
String base64Encode = base64.encode(bytes);
@ -33,7 +33,7 @@ class ImageOptions {
if (Platform.isAndroid) {
galleryImageAndroid(image);
} else {
File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.gallery, imageQuality: 20))?.path ?? "");
File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.gallery, imageQuality: 10))?.path ?? "");
String fileName = _image.path;
var bytes = File(fileName).readAsBytesSync();
String base64Encode = base64.encode(bytes);
@ -74,7 +74,7 @@ class ImageOptions {
if (Platform.isAndroid) {
galleryImageAndroid(image);
} else {
File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.gallery, imageQuality: 20))?.path ?? "");
File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.gallery, imageQuality: 10))?.path ?? "");
String fileName = _image.path;
var bytes = File(fileName).readAsBytesSync();
String base64Encode = base64.encode(bytes);
@ -91,7 +91,7 @@ class ImageOptions {
if (Platform.isAndroid) {
cameraImageAndroid(image);
} else {
File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.camera, imageQuality: 20))?.path ?? "");
File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.camera, imageQuality: 10))?.path ?? "");
String fileName = _image.path;
var bytes = File(fileName).readAsBytesSync();
String base64Encode = base64.encode(bytes);
@ -114,7 +114,7 @@ class ImageOptions {
}
void galleryImageAndroid(Function(String, File) image) async {
File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.gallery, imageQuality: 20))?.path ?? "");
File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.gallery, imageQuality: 10))?.path ?? "");
String fileName = _image.path;
var bytes = File(fileName).readAsBytesSync();
String base64Encode = base64.encode(bytes);
@ -124,7 +124,7 @@ void galleryImageAndroid(Function(String, File) image) async {
}
void cameraImageAndroid(Function(String, File) image) async {
File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.camera, imageQuality: 20))?.path ?? "");
File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.camera, imageQuality: 10))?.path ?? "");
String fileName = _image.path;
var bytes = File(fileName).readAsBytesSync();
String base64Encode = base64.encode(bytes);

@ -14,6 +14,7 @@ import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/models/generic_response_model.dart';
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/nfc/nfc_reader_sheet.dart';
@ -144,14 +145,28 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
Utils.showLoading(context);
try {
GenericResponseModel? g = await DashboardApiClient().markAttendance(pointType: 2, nfcValue: nfcId, isGpsRequired: isNfcLocationEnabled, lat: lat, long: lng);
bool status = await model.fetchAttendanceTracking(context);
Utils.hideLoading(context);
showMDialog(
context,
backgroundColor: Colors.transparent,
isDismissable: false,
child: SuccessDialog(widget.isFromDashboard),
);
if(g?.messageStatus != 1) {
Utils.hideLoading(context);
showDialog(
context: context,
builder: (cxt) => ConfirmDialog(
message: g?.errorEndUserMessage ?? "Unexpected error occurred",
onTap: () {
Navigator.pop(context);
},
),
);
} else {
bool status = await model.fetchAttendanceTracking(context);
Utils.hideLoading(context);
showMDialog(
context,
backgroundColor: Colors.transparent,
isDismissable: false,
child: SuccessDialog(widget.isFromDashboard),
);
}
} catch (ex) {
print(ex);
Utils.hideLoading(context);
@ -166,14 +181,27 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
Utils.showLoading(context);
try {
GenericResponseModel? g = await DashboardApiClient().markAttendance(pointType: 2, nfcValue: nfcId ?? "", isGpsRequired: isNfcLocationEnabled, lat: lat, long: lng);
bool status = await model.fetchAttendanceTracking(context);
Utils.hideLoading(context);
showMDialog(
context,
backgroundColor: Colors.transparent,
isDismissable: false,
child: SuccessDialog(widget.isFromDashboard),
);
if(g?.messageStatus != 1) {
Utils.hideLoading(context);
showDialog(
context: context,
builder: (cxt) => ConfirmDialog(
message: g?.errorEndUserMessage ?? "Unexpected error occurred",
onTap: () {
Navigator.pop(context);
},
),
);
} else {
bool status = await model.fetchAttendanceTracking(context);
Utils.hideLoading(context);
showMDialog(
context,
backgroundColor: Colors.transparent,
isDismissable: false,
child: SuccessDialog(widget.isFromDashboard),
);
}
} catch (ex) {
print(ex);
Utils.hideLoading(context);

@ -79,11 +79,6 @@ dependencies:
pull_to_refresh: ^2.0.0
# lottie json animations
lottie: any
# Steps Progress
steps_indicator: ^1.3.0
# Marathon Card Swipe
appinio_swiper: ^1.1.1
expandable: ^5.0.1

Loading…
Cancel
Save