Merge remote-tracking branch 'origin/sultan-dev' into development_aamir

# Conflicts:
#	android/app/src/main/AndroidManifest.xml
#	android/gradle/wrapper/gradle-wrapper.properties
#	lib/api/chat/chat_api_client.dart
#	lib/app_state/app_state.dart
#	lib/classes/consts.dart
#	lib/generated_plugin_registrant.dart
#	lib/main.dart
#	lib/provider/chat_provider_model.dart
#	lib/ui/chat/group_chat_detaied_screen.dart
#	lib/ui/landing/dashboard_screen.dart
#	lib/ui/login/login_screen.dart
#	lib/ui/my_attendance/dynamic_screens/dynamic_input_screen.dart
#	lib/widgets/image_picker.dart
#	pubspec.yaml
development_aamir
Aamir Muhammad 2 years ago
commit 2f22519d86

@ -71,10 +71,10 @@ android {
signingConfig signingConfigs.debug
}
release {
signingConfig signingConfigs.debug
minifyEnabled false
shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
@ -85,6 +85,4 @@ flutter {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.squareup.okhttp3:okhttp:4.9.1'
}

@ -1,27 +0,0 @@
-ignorewarnings
-keepattributes *Annotation*
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
-keep class com.huawei.hianalytics.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}
-keep class com.huawei.hms.flutter.**{*;}
-keep class com.hiennv.flutter_callkit_incoming.** { *; }
-keep class microsoft.aspnet.signalr.client.hubs.** { *; }
-keep class com.microsoft.signalr.** { *; }
-keep class tvi.webrtc.** { *; }
-keep interface com.microsoft.signalr.** { *; }
-repackageclasses
## Flutter wrapper
-keep class io.flutter.app.** { *; }
-keep class io.flutter.plugin.** { *; }
-keep class io.flutter.util.** { *; }
-keep class io.flutter.view.** { *; }
-keep class io.flutter.** { *; }
-keep class io.flutter.plugins.** { *; }
-dontwarn io.flutter.embedding.**

@ -35,7 +35,6 @@
android:icon="@mipmap/ic_launcher"
android:label="Mohemm"
android:extractNativeLibs="true"
android:usesCleartextTraffic="true"
android:networkSecurityConfig="@xml/network_security_config"
android:roundIcon="@mipmap/ic_launcher_round">
<provider

@ -1,5 +1,5 @@
buildscript {
ext.kotlin_version = '1.8.21'
ext.kotlin_version = '1.7.20'
repositories {
google()
mavenCentral()

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

@ -111,6 +111,8 @@ 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? requestBody;
print(url);
print(jsonObject);
late Map<String, String> stringObj;
if (jsonObject != null) {
requestBody = jsonEncode(jsonObject);
@ -124,6 +126,7 @@ 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() ?? ""));
print(stringObj);
}
return await _postForResponse(url, isFormData ? stringObj : requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes);

@ -34,7 +34,6 @@ class ChatApiClient {
"employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(),
"password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG",
"isMobile": true,
"platform": Platform.isIOS ? "ios" : "android",
"deviceToken": AppState().getIsHuawei ? AppState().getHuaweiPushToken : AppState().getDeviceToken,
"isHuaweiDevice": AppState().getIsHuawei,
"platform": Platform.isIOS ? "ios" : "android", // ios, android
@ -142,14 +141,14 @@ class ChatApiClient {
}
// Upload Chat Media
Future<Object?> uploadMedia(String userId, File file) async {
Future<Object?> uploadMedia(String userId, File file, String fileSource) async {
if (kDebugMode) {
print("${ApiConsts.chatMediaImageUploadUrl}upload");
print(AppState().chatDetails!.response!.token);
}
dynamic request = MultipartRequest('POST', Uri.parse('${ApiConsts.chatMediaImageUploadUrl}upload'));
request.fields.addAll({'userId': userId, 'fileSource': '1'});
request.fields.addAll({'userId': userId, 'fileSource': fileSource});
request.files.add(await MultipartFile.fromPath('files', file.path));
request.headers.addAll({'Authorization': 'Bearer ${AppState().chatDetails!.response!.token}'});
StreamedResponse response = await request.send();
@ -161,10 +160,10 @@ class ChatApiClient {
}
// Download File For Chat
Future<Uint8List> downloadURL({required String fileName, required String fileTypeDescription}) async {
Future<Uint8List> downloadURL({required String fileName, required String fileTypeDescription, required int fileSource}) async {
Response response = await ApiClient().postJsonForResponse(
"${ApiConsts.chatMediaImageUploadUrl}download",
{"fileType": fileTypeDescription, "fileName": fileName, "fileSource": 1},
{"fileType": fileTypeDescription, "fileName": fileName, "fileSource": fileSource},
token: AppState().chatDetails!.response!.token,
);
Uint8List data = Uint8List.fromList(response.bodyBytes);

@ -194,6 +194,7 @@ class AppState {
bool cancelRequestTrancsection = true;
String _iosVoipPlayerID = "";
String get iosVoipPlayerID => _iosVoipPlayerID;

@ -1,8 +1,8 @@
class ApiConsts {
//static String baseUrl = "http://10.200.204.20:2801/"; // Local server
// static String baseUrl = "https://erptstapp.srca.org.sa"; // SRCA server
static String baseUrl = "https://uat.hmgwebservices.com"; // UAT ser343622ver
// static String baseUrl = "https://hmgwebservices.com"; // Live server
// static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server
static String baseUrl = "https://hmgwebservices.com"; // Live server
static String baseUrlServices = baseUrl + "/Services/"; // server
// static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server
static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/";
@ -18,13 +18,13 @@ class ApiConsts {
static String chatLoginTokenUrl = chatServerBaseApiUrl + "user/";
static String chatHubConnectionUrl = chatServerBaseUrl + "ConnectionChatHub";
//Groups
static String getGroupByUserId = chatServerBaseApiUrl + "group/getgroupsbyuserid/";
static String deleteGroup = chatServerBaseApiUrl + "group/updateGroupIsDeleted/";
static String updateGroupAdmin = chatServerBaseApiUrl + "group/updateGroupAdmin/";
static String getGroupChatHistoryAsync = chatServerBaseApiUrl + "GroupChat/GetGroupChatHistoryAsync/";
static String addGroupsAndUsers = chatServerBaseApiUrl + "group/addgroupandusers/";
static String updateGroupsAndUsers = chatServerBaseApiUrl + "group/updategroupandusers/";
//Groups
static String getGroupByUserId = chatServerBaseApiUrl + "group/getgroupsbyuserid/";
static String deleteGroup = chatServerBaseApiUrl + "group/updateGroupIsDeleted/";
static String updateGroupAdmin = chatServerBaseApiUrl + "group/updateGroupAdmin/";
static String getGroupChatHistoryAsync = chatServerBaseApiUrl + "GroupChat/GetGroupChatHistoryAsync/";
static String addGroupsAndUsers = chatServerBaseApiUrl + "group/addgroupandusers/";
static String updateGroupsAndUsers = chatServerBaseApiUrl + "group/updategroupandusers/";
// static String chatSearchMember = chatLoginTokenUrl + "user/";
static String chatRecentUrl = chatServerBaseApiUrl + "UserChatHistory/"; //For a Mem
@ -36,11 +36,7 @@ class ApiConsts {
static String oneSignalAppID = "472e4582-5c44-47ab-a5f5-9369b8967107";
//Brain Marathon Constants
static String marathonBaseUrlLive = "https://marathoon.com/service/api/";
static String marathonBaseUrlUAT = "https://marathoon.com/uatservice/api/";
static String marathonBaseUrl = marathonBaseUrlLive;
// static String marathonBaseUrl = marathonBaseUrlUAT;
static String marathonBaseUrl = "https://marathoon.com/service/api/";
static String marathonBaseUrlServices = "https://marathoon.com/service/";
static String marathonParticipantLoginUrl = marathonBaseUrl + "auth/participantlogin";
static String marathonProjectGetUrl = marathonBaseUrl + "Project/Project_Get";
@ -53,6 +49,7 @@ class ApiConsts {
static String marathonGetMarathonersCount = marathonBaseUrl + "Participant/GetRemainingParticipants";
//DummyCards for the UI
static CardContent dummyQuestion = const CardContent();
static int tabletMinLength = 500;
}

@ -73,7 +73,7 @@ class AppNotifications {
if (initialMessage != null) _handleMessage(initialMessage);
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
if (message.notification != null) _handleMessage(message);
_handleMessage(message);
});
FirebaseMessaging.onMessageOpenedApp.listen(_handleOpenApp);
@ -134,23 +134,26 @@ class AppNotifications {
Utils.saveStringFromPrefs("isAppOpendByChat", "false");
GetNotificationsResponseModel notification = GetNotificationsResponseModel();
notification.createdOn = DateUtil.getMonthDayYearDateFormatted(DateTime.now());
notification.messageTypeData = message.data['picture'];
notification.message = message.data['message'];
notification.notificationType = message.data["NotificationType"].toString();
if (message.data["NotificationType"] == "2") {
notification.videoURL = message.data["VideoUrl"];
}
if (message.notification != null) {
notification.createdOn = DateUtil.getMonthDayYearDateFormatted(DateTime.now());
notification.messageTypeData = message.data['picture'];
notification.message = message.data['message'];
notification.notificationType = message.data["NotificationType"].toString();
if (message.data["NotificationType"] == "2") {
notification.videoURL = message.data["VideoUrl"];
}
Future.delayed(Duration(seconds: 5), () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) => NotificationsDetailsPage(
notification: notification,
Future.delayed(Duration(seconds: 5), () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) => NotificationsDetailsPage(
notification: notification,
),
),
),
);
});
);
});
}
if (message.data.isNotEmpty && message.data["messageType"] == 'chat') {
Utils.saveStringFromPrefs("isAppOpendByChat", "true");
Utils.saveStringFromPrefs("notificationData", message.data["user_chat_history_response"].toString());
@ -187,8 +190,6 @@ class AppNotifications {
});
}
}
}
const AndroidNotificationChannel channel = AndroidNotificationChannel(

@ -10,16 +10,16 @@ import 'package:audio_session/audio_session_web.dart';
import 'package:file_picker/_internal/file_picker_web.dart';
import 'package:firebase_core_web/firebase_core_web.dart';
import 'package:firebase_messaging_web/firebase_messaging_web.dart';
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
import 'package:fluttertoast/fluttertoast_web.dart';
import 'package:geolocator_web/geolocator_web.dart';
import 'package:image_picker_for_web/image_picker_for_web.dart';
import 'package:just_audio_web/just_audio_web.dart';
// import 'package:record_web/record_web.dart';
import 'package:shared_preferences_web/shared_preferences_web.dart';
import 'package:url_launcher_web/url_launcher_web.dart';
import 'package:video_player_web/video_player_web.dart';
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
// ignore: public_member_api_docs
void registerPlugins(Registrar registrar) {
AudioSessionWeb.registerWith(registrar);
@ -30,7 +30,6 @@ void registerPlugins(Registrar registrar) {
GeolocatorPlugin.registerWith(registrar);
ImagePickerPlugin.registerWith(registrar);
JustAudioPlugin.registerWith(registrar);
//RecordPluginWeb.registerWith(registrar);
SharedPreferencesPlugin.registerWith(registrar);
UrlLauncherPlugin.registerWith(registrar);
VideoPlayerPlugin.registerWith(registrar);

@ -20,6 +20,7 @@ import 'package:provider/provider.dart';
import 'package:provider/single_child_widget.dart';
import 'package:signalr_netcore/hub_connection.dart';
import 'package:sizer/sizer.dart';
late HubConnection chatHubConnection;
// test uat account
// username 199067

@ -4,6 +4,8 @@ class CreateGroupRequest {
String? groupName;
int? adminUserId;
List<ChatUser>? groupUserList;
List<ChatUser>? addedUsers;
List<ChatUser>? removedUsers;
bool? canAttach;
bool? canAudioC;
bool? canShareS;
@ -15,6 +17,8 @@ class CreateGroupRequest {
{this.groupName,
this.adminUserId,
this.groupUserList,
this.addedUsers,
this.removedUsers,
this.canAttach,
this.canAudioC,
this.canShareS,
@ -27,12 +31,24 @@ class CreateGroupRequest {
CreateGroupRequest.fromJson(Map<String, dynamic> json) {
groupName = json['groupName'];
adminUserId = json['adminUserId'];
if (json['removedUsers'] != null) {
groupUserList = <ChatUser>[];
json['removedUsers'].forEach((v) {
groupUserList!.add(new ChatUser.fromJson(v));
});
}
if (json['groupUserList'] != null) {
groupUserList = <ChatUser>[];
json['groupUserList'].forEach((v) {
groupUserList!.add(new ChatUser.fromJson(v));
});
}
if (json['addedUsers'] != null) {
groupUserList = <ChatUser>[];
json['addedUsers'].forEach((v) {
groupUserList!.add(new ChatUser.fromJson(v));
});
}
canAttach = json['canAttach'];
canAudioC = json['canAudioC'];
canShareS = json['canShareS'];
@ -50,6 +66,14 @@ class CreateGroupRequest {
data['groupUserList'] =
this.groupUserList!.map((v) => v.toJson()).toList();
}
if (this.addedUsers != null) {
data['addedUsers'] =
this.addedUsers!.map((v) => v.toJson()).toList();
}
if (this.removedUsers != null) {
data['removedUsers'] =
this.removedUsers!.map((v) => v.toJson()).toList();
}
data['canAttach'] = this.canAttach;
data['canAudioC'] = this.canAudioC;
data['canShareS'] = this.canShareS;

@ -1,7 +1,7 @@
import 'dart:convert';
class GetUserGroups {
List<GroupResponse>? groupresponse;
List<GroupResponse>? groupresponse =[];
Null? errorResponses;
GetUserGroups({this.groupresponse, this.errorResponses});

@ -86,15 +86,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
/// Search Provider
List<ChatUser>? chatUsersList = [];
int pageNo = 1;
bool disbaleChatForThisUser = false;
List<groups.GroupResponse>? uGroups = [], searchGroups = [];
bool disbaleChatForThisUser = false;
bool disableChatForThisUser = false;
bool isUserOnline = false;
bool isCall = false;
userLoginToken.UserAutoLoginModel userLoginData = userLoginToken.UserAutoLoginModel();
Future<void> getUserAutoLoginToken() async {
try {
userLoginToken.UserAutoLoginModel userLoginResponse = await ChatApiClient().getUserLoginToken();
@ -111,7 +108,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
Utils.showToast(
userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr",
);
disableChatForThisUser = true;
disableChatForThisUser = false;
isUserOnline = false;
if (Platform.isIOS) {
AppState().setisUserOnline = false;
@ -140,11 +139,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
chatHubConnection.on("OnDeliveredChatUserAsync", onMsgReceived);
chatHubConnection.on("OnGetChatConversationCount", onNewChatConversion);
ccProvider.initCallListeners(context: context);
//group On message
chatHubConnection.on("OnDeliveredGroupChatHistoryAsync", onGroupMsgReceived);
ccProvider.initCallListeners(context: context);
}
Future<HubConnection> getHubConnection() async {
@ -164,10 +163,14 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
chatHubConnection.on("OnUserTypingAsync", onUserTyping);
chatHubConnection.on("OnUserCountAsync", userCountAsync);
// chatHubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow);
chatHubConnection.on("OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered);
chatHubConnection.on("OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus);
chatHubConnection.on("OnGetGroupUserStatusAsync", getGroupUserStatus);
chatHubConnection.on(
"OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered);
chatHubConnection.on(
"OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus);
chatHubConnection.on(
"OnGetGroupUserStatusAsync", getGroupUserStatus);
chatHubConnection.on(
"OnAddGroupChatHistoryAsync", groupChatHistoryAsync);
//
// {"type":1,"target":"","arguments":[[{"id":217869,"userName":"Sultan.Khan","email":"Sultan.Khan@cloudsolutions.com.sa","phone":null,"title":"Sultan.Khan","userStatus":1,"image":null,"unreadMessageCount":0,"userAction":3,"isPin":false,"isFav":false,"isAdmin":false,"rKey":null,"totalCount":0,"isHuaweiDevice":false,"deviceToken":null},{"id":15153,"userName":"Tamer.Fanasheh","email":"Tamer.F@cloudsolutions.com.sa","phone":null,"title":"Tamer Fanasheh","userStatus":2,"image":null,"unreadMessageCount":0,"userAction":3,"isPin":false,"isFav":false,"isAdmin":true,"rKey":null,"totalCount":0,"isHuaweiDevice":false,"deviceToken":null}]]}
@ -179,7 +182,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
Future<void> getUserRecentChats() async {
ChatUserModel recentChat = await ChatApiClient().getRecentChats();
ChatUserModel favUList = await ChatApiClient().getFavUsers();
// userGroups = await ChatApiClient().getGroupsByUserId();
userGroups = await ChatApiClient().getGroupsByUserId();
if (favUList.response != null && recentChat.response != null) {
favUsersList = favUList.response!;
favUsersList.sort((ChatUser a, ChatUser b) => a.userName!.toLowerCase().compareTo(b.userName!.toLowerCase()));
@ -293,10 +296,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
List<groupchathistory.GetGroupChatHistoryAsync> getGroupChatHistoryAsync(String str) =>
List<groupchathistory.GetGroupChatHistoryAsync>.from(json.decode(str).map((x) => groupchathistory.GetGroupChatHistoryAsync.fromJson(x)));
Future<dynamic> uploadAttachments(String userId, File file) async {
Future<dynamic> uploadAttachments(String userId, File file, String fileSource) async {
dynamic result;
try {
Object? response = await ChatApiClient().uploadMedia(userId, file);
Object? response = await ChatApiClient().uploadMedia(userId, file, fileSource);
if (response != null) {
result = response;
} else {
@ -321,8 +324,13 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
notifyListeners();
}
void getGroupUserStatus(List<Object?>? args) {
//note: need to implement this function...
void getGroupUserStatus(List<Object?>? args){
//note: need to implement this function when group user status
print(args);
}
void groupChatHistoryAsync(List<Object?>? args){
//need to imlement this event when any group details updated.
print(args);
}
@ -421,15 +429,22 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
data.first.currentUserId = temp.first.targetUserId;
data.first.currentUserName = temp.first.targetUserName;
data.first.currentUserEmail = temp.first.targetUserEmail;
if (data.first.fileTypeId == 12 || data.first.fileTypeId == 4 || data.first.fileTypeId == 3) {
data.first.image = await ChatApiClient().downloadURL(fileName: data.first.contant!, fileTypeDescription: data.first.fileTypeResponse!.fileTypeDescription ?? "image/jpg");
data.first.image = await ChatApiClient().downloadURL(fileName: data.first.contant!, fileTypeDescription: data.first.fileTypeResponse!.fileTypeDescription ?? "image/jpg",fileSource: 1);
}
if (data.first.userChatReplyResponse != null) {
if (data.first.fileTypeResponse != null) {
if (data.first.userChatReplyResponse!.fileTypeId == 12 || data.first.userChatReplyResponse!.fileTypeId == 4 || data.first.userChatReplyResponse!.fileTypeId == 3) {
data.first.userChatReplyResponse!.image =
await ChatApiClient().downloadURL(fileName: data.first.userChatReplyResponse!.contant!, fileTypeDescription: data.first.fileTypeResponse!.fileTypeDescription ?? "image/jpg");
if (data.first.userChatReplyResponse!.fileTypeId == 12 ||
data.first.userChatReplyResponse!.fileTypeId == 4 ||
data.first.userChatReplyResponse!.fileTypeId == 3) {
data.first.userChatReplyResponse!.image = await ChatApiClient()
.downloadURL(
fileName: data.first.userChatReplyResponse!.contant!,
fileTypeDescription:
data.first.fileTypeResponse!.fileTypeDescription ??
"image/jpg",
fileSource:1
);
data.first.userChatReplyResponse!.isImageLoaded = true;
}
}
@ -501,14 +516,30 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
// data.first.currentUserId = temp.first.currentUserId;
// data.first.currentUserName = temp.first.currentUserName;
if (data.first.fileTypeId == 12 || data.first.fileTypeId == 4 || data.first.fileTypeId == 3) {
data.first.image = await ChatApiClient().downloadURL(fileName: data.first.contant!, fileTypeDescription: data.first.fileTypeResponse!.fileTypeDescription ?? "image/jpg");
if (data.first.fileTypeId == 12 ||
data.first.fileTypeId == 4 ||
data.first.fileTypeId == 3) {
data.first.image = await ChatApiClient().downloadURL(
fileName: data.first.contant!,
fileTypeDescription:
data.first.fileTypeResponse!.fileTypeDescription ??
"image/jpg",
fileSource:2
);
}
if (data.first.groupChatReplyResponse != null) {
if (data.first.fileTypeResponse != null) {
if (data.first.groupChatReplyResponse!.fileTypeId == 12 || data.first.groupChatReplyResponse!.fileTypeId == 4 || data.first.groupChatReplyResponse!.fileTypeId == 3) {
data.first.groupChatReplyResponse!.image =
await ChatApiClient().downloadURL(fileName: data.first.groupChatReplyResponse!.contant!, fileTypeDescription: data.first.fileTypeResponse!.fileTypeDescription ?? "image/jpg");
if (data.first.groupChatReplyResponse!.fileTypeId == 12 ||
data.first.groupChatReplyResponse!.fileTypeId == 4 ||
data.first.groupChatReplyResponse!.fileTypeId == 3) {
data.first.groupChatReplyResponse!.image = await ChatApiClient()
.downloadURL(
fileName: data.first.groupChatReplyResponse!.contant!,
fileTypeDescription:
data.first.fileTypeResponse!.fileTypeDescription ??
"image/jpg",
fileSource:2);
data.first.groupChatReplyResponse!.isImageLoaded = true;
}
}
@ -587,8 +618,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
if (isChatScreenActive && data.first.currentUserId == receiverID) {
int index = userChatHistory.indexWhere((SingleUserChatModel element) => element.userChatHistoryId == 0);
logger.d(index);
userChatHistory[index] = data.first;
}
@ -649,6 +678,14 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
return 13;
case ".mp3":
return 14;
case ".mp4":
return 16;
case ".mov":
return 16;
case ".avi":
return 16;
case ".flv":
return 16;
default:
return 0;
}
@ -686,6 +723,14 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
return "audio/aac";
case ".mp3":
return "audio/mp3";
case ".mp4":
return "video/mp4";
case ".avi":
return "video/avi";
case ".flv":
return "video/flv";
case ".mov":
return "video/mov";
default:
return "";
}
@ -814,7 +859,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
if (kDebugMode) {
logger.i("model data: " + jsonEncode(data));
}
groupChatHistory.insert(0, data);
// groupChatHistory.insert(0, data);
isTextMsg = false;
isReplyMsg = false;
isAttachmentMsg = false;
@ -887,7 +932,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
else if (!isTextMsg && isAttachmentMsg && !isVoiceMsg && !isReplyMsg) {
logger.d("// Normal Image Message");
Utils.showLoading(context);
dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile);
dynamic value = await uploadAttachments(
AppState().chatDetails!.response!.id.toString(), selectedFile,'2');
String? ext = getFileExtension(selectedFile.path);
Utils.hideLoading(context);
sendGroupChatToServer(
@ -907,7 +953,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
} else if (!isTextMsg && isAttachmentMsg && !isVoiceMsg && isReplyMsg) {
logger.d("// Image as Reply Msg");
Utils.showLoading(context);
dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile);
dynamic value = await uploadAttachments(
AppState().chatDetails!.response!.id.toString(), selectedFile,'2');
String? ext = getFileExtension(selectedFile.path);
Utils.hideLoading(context);
sendGroupChatToServer(
@ -943,8 +990,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
isPlaying = false;
isRecoding = false;
Utils.showLoading(context);
dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), voiceFile);
String? ext = getFileExtension(voiceFile.path);
dynamic value = await uploadAttachments(
AppState().chatDetails!.response!.id.toString(), voiceFile,'2');
String? ext = getFileExtension(voiceFile.path);
Utils.hideLoading(context);
sendGroupChatToServer(
chatEventId: 2,
@ -979,8 +1027,9 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
isRecoding = false;
Utils.showLoading(context);
dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), voiceFile);
String? ext = getFileExtension(voiceFile.path);
dynamic value = await uploadAttachments(
AppState().chatDetails!.response!.id.toString(), voiceFile,'2');
String? ext = getFileExtension(voiceFile.path);
Utils.hideLoading(context);
sendGroupChatToServer(
chatEventId: 2,
@ -1081,7 +1130,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
else if (!isTextMsg && isAttachmentMsg && !isVoiceMsg && !isReplyMsg) {
logger.d("// Normal Image Message");
Utils.showLoading(context);
dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile);
dynamic value = await uploadAttachments(
AppState().chatDetails!.response!.id.toString(), selectedFile,'1');
String? ext = getFileExtension(selectedFile.path);
Utils.hideLoading(context);
sendChatToServer(
@ -1100,7 +1150,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
} else if (!isTextMsg && isAttachmentMsg && !isVoiceMsg && isReplyMsg) {
logger.d("// Image as Reply Msg");
Utils.showLoading(context);
dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile);
dynamic value = await uploadAttachments(
AppState().chatDetails!.response!.id.toString(), selectedFile,'1');
String? ext = getFileExtension(selectedFile.path);
Utils.hideLoading(context);
sendChatToServer(
@ -1135,7 +1186,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
isPlaying = false;
isRecoding = false;
Utils.showLoading(context);
dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), voiceFile);
dynamic value = await uploadAttachments(
AppState().chatDetails!.response!.id.toString(), voiceFile, '1');
String? ext = getFileExtension(voiceFile.path);
Utils.hideLoading(context);
sendChatToServer(
@ -1169,7 +1221,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
isRecoding = false;
Utils.showLoading(context);
dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), voiceFile);
dynamic value = await uploadAttachments(
AppState().chatDetails!.response!.id.toString(), voiceFile, '1');
String? ext = getFileExtension(voiceFile.path);
Utils.hideLoading(context);
sendChatToServer(
@ -1271,8 +1324,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
bool checkFileSize(String path) {
int fileSizeLimit = 1024;
File f = File(path);
double fileSizeInKB = f.lengthSync() / 1024;
double fileSizeInMB = fileSizeInKB / 1024;
double fileSizeInKB = f.lengthSync() / 5000;
double fileSizeInMB = fileSizeInKB / 5000;
if (fileSizeInKB > fileSizeLimit) {
return false;
} else {
@ -1453,6 +1506,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
pChatHistory?.clear();
uGroups?.clear();
searchGroup?.clear();
// callP.stopListeners();
chatHubConnection.stop();
AppState().chatDetails = null;
}
@ -1564,10 +1618,23 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
}
Future<void> getChatMedia(BuildContext context, {required String fileName, required String fileTypeName, required int fileTypeID}) async {
Future<void> getChatMedia(BuildContext context,
{required String fileName,
required String fileTypeName,
required int fileTypeID,
required int fileSource}) async {
Utils.showLoading(context);
if (fileTypeID == 1 || fileTypeID == 5 || fileTypeID == 7 || fileTypeID == 6 || fileTypeID == 8 || fileTypeID == 2) {
Uint8List encodedString = await ChatApiClient().downloadURL(fileName: fileName, fileTypeDescription: getFileTypeDescription(fileTypeName));
if (fileTypeID == 1 ||
fileTypeID == 5 ||
fileTypeID == 7 ||
fileTypeID == 6 ||
fileTypeID == 8 ||
fileTypeID == 2 || fileTypeID ==16) {
Uint8List encodedString = await ChatApiClient().downloadURL(
fileName: fileName,
fileTypeDescription: getFileTypeDescription(fileTypeName),
fileSource: fileSource
);
try {
String path = await downChatMedia(encodedString, fileTypeName ?? "");
Utils.hideLoading(context);

@ -154,7 +154,7 @@ class _StartCallPageState extends State<StartCallPage> {
RTCVideoView(
provider.remoteRenderer!,
objectFit: RTCVideoViewObjectFit.RTCVideoViewObjectFitContain,
filterQuality: FilterQuality.high,
// filterQuality: FilterQuality.high,
key: const Key('remote'),
),
if (provider.isVideoCall)
@ -174,7 +174,7 @@ class _StartCallPageState extends State<StartCallPage> {
child: RTCVideoView(
provider.localVideoRenderer!,
mirror: true,
filterQuality: FilterQuality.high,
// filterQuality: FilterQuality.high,
objectFit: RTCVideoViewObjectFit.RTCVideoViewObjectFitCover,
),
),

@ -82,7 +82,7 @@ class ChatBubble extends StatelessWidget {
}
} else {
Utils.showLoading(context);
Uint8List encodedString = await ChatApiClient().downloadURL(fileName: data.contant!, fileTypeDescription: provider.getFileTypeDescription(data.fileTypeResponse!.fileTypeName ?? ""));
Uint8List encodedString = await ChatApiClient().downloadURL(fileName: data.contant!, fileTypeDescription: provider.getFileTypeDescription(data.fileTypeResponse!.fileTypeName ?? ""), fileSource:1);
// try {
File sFile = await provider.downChatVoice(encodedString, data.fileTypeResponse!.fileTypeName ?? "", data);
if (sFile.path.isEmpty) {
@ -342,7 +342,7 @@ class ChatBubble extends StatelessWidget {
);
} else {
return FutureBuilder<Uint8List>(
future: ChatApiClient().downloadURL(fileName: fileName, fileTypeDescription: fileTypeDescription),
future: ChatApiClient().downloadURL(fileName: fileName, fileTypeDescription: fileTypeDescription, fileSource:1),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.connectionState != ConnectionState.waiting) {
if (snapshot.data == null) {

@ -175,7 +175,7 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
// || m.userChatHistory[i].fileTypeId! == 2
) {
m.getChatMedia(context,
fileTypeName: m.userChatHistory[i].fileTypeResponse!.fileTypeName ?? "", fileTypeID: m.userChatHistory[i].fileTypeId!, fileName: m.userChatHistory[i].contant!);
fileTypeName: m.userChatHistory[i].fileTypeResponse!.fileTypeName ?? "", fileTypeID: m.userChatHistory[i].fileTypeId!, fileName: m.userChatHistory[i].contant!, fileSource:1);
}
}
});

@ -68,7 +68,8 @@ class _ChatHomeState extends State<ChatHome> {
fetchAgain();
return Scaffold(
backgroundColor: MyColors.white,
appBar: AppBarWidget(context, title: LocaleKeys.chat.tr(), showHomeButton: true),
appBar: AppBarWidget(context, title: LocaleKeys.chat.tr(), showHomeButton: true, isBackButton: false),
body: Column(
children: <Widget>[
Container(
@ -91,7 +92,7 @@ class _ChatHomeState extends State<ChatHome> {
child: Row(
children: <Widget>[
myTab(LocaleKeys.mychats.tr(), 0),
// myTab(LocaleKeys.group.tr(), 1),
myTab(LocaleKeys.group.tr(), 1),
myTab(LocaleKeys.favorite.tr(), 2),
AppState().getempStatusIsManager ? myTab(LocaleKeys.myTeam.tr(), 3) : const SizedBox(),
],
@ -107,7 +108,7 @@ class _ChatHomeState extends State<ChatHome> {
},
children: <Widget>[
ChatHomeScreen(),
// GropChatHomeScreen(),
GropChatHomeScreen(),
ChatFavoriteUsersScreen(),
AppState().getempStatusIsManager ? const MyTeamScreen() : const SizedBox(),
],

@ -217,9 +217,10 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
child: Container(
width: 60,
height: 60,
decoration: const BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
//shape: BoxShape.circle,
gradient:const LinearGradient(
transform: GradientRotation(.46),
begin: Alignment.topRight,
end: Alignment.bottomLeft,

@ -36,7 +36,6 @@ class CreateGroupBottomSheet extends StatefulWidget {
Function(ReplacementList) onSelectEmployee;
bool fromChat;
groups.GroupResponse groupDetails;
CreateGroupBottomSheet({
Key? key,
required this.title,
@ -77,7 +76,8 @@ class _CreateGroupBottomSheetState extends State<CreateGroupBottomSheet> {
int _selectedSearchIndex = 0;
List<ChatUser> selectedUsers = [];
List<ChatUser> addedUser = [];
List<ChatUser> removedUser = [];
void fetchUserByInput({bool isNeedLoading = true}) async {
try {
Utils.showLoading(context);
@ -397,6 +397,8 @@ class _CreateGroupBottomSheetState extends State<CreateGroupBottomSheet> {
if (user.isNotEmpty) {
user.first.isChecked = false;
}
selectedUsers[index2].userAction =2;
removedUser.add(selectedUsers[index2]);
selectedUsers.remove(
selectedUsers[index2]);
});
@ -535,8 +537,12 @@ class _CreateGroupBottomSheetState extends State<CreateGroupBottomSheet> {
if (provider.chatUsersList![index]
.isChecked ==
true) {
provider
.chatUsersList![index].userAction =1;
selectedUsers.add(provider
.chatUsersList![index]);
} else {
selectedUsers.remove(provider
.chatUsersList![index]);
@ -677,7 +683,7 @@ class _CreateGroupBottomSheetState extends State<CreateGroupBottomSheet> {
admin.totalCount = 0;
mainUsers.add(admin);
CreateGroupRequest request = CreateGroupRequest(
groupUserList: [...selectedUsers, ...mainUsers].toList(),
groupUserList: [...selectedUsers, ...mainUsers, ...removedUser].toList(),
canArchive: false,
isMeeting: false,
canShareS: isShareScreen,

@ -199,9 +199,10 @@ class _GropChatHomeScreenState extends State<GropChatHomeScreen> {
child: Container(
width: 60,
height: 60,
decoration: const BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
// shape: BoxShape.circle,
gradient:const LinearGradient(
transform: GradientRotation(.46),
begin: Alignment.topRight,
end: Alignment.bottomLeft,

@ -22,6 +22,7 @@ import 'package:mohem_flutter_app/ui/chat/common.dart';
import 'package:path_provider/path_provider.dart';
import 'package:provider/provider.dart';
import 'package:rxdart/rxdart.dart';
import 'package:video_player/video_player.dart';
class GroupChatBubble extends StatelessWidget {
GroupChatBubble({Key? key, required this.dateTime, required this.cItem})
@ -100,7 +101,7 @@ class GroupChatBubble extends StatelessWidget {
Uint8List encodedString = await ChatApiClient().downloadURL(
fileName: data.contant!,
fileTypeDescription: provider.getFileTypeDescription(
data.fileTypeResponse!.fileTypeName ?? ""));
data.fileTypeResponse!.fileTypeName ?? ""), fileSource: 2);
// try {
File sFile = await provider.downChatVoice(
encodedString, data.fileTypeResponse!.fileTypeName ?? "", data);
@ -245,8 +246,11 @@ class GroupChatBubble extends StatelessWidget {
child: showImage(
isReplyPreview: false,
fileName: cItem.contant!,
fileTypeDescription:
cItem.fileTypeResponse!.fileTypeDescription)
fileTypeDescription: cItem.fileTypeResponse != null &&
cItem.fileTypeResponse!.fileTypeDescription !=
null
? cItem.fileTypeResponse!.fileTypeDescription
: cItem.fileTypeResponse!.fileTypeName)
.onPress(() {
showDialog(
context: context,
@ -258,17 +262,19 @@ class GroupChatBubble extends StatelessWidget {
),
).paddingOnly(bottom: 4),
if (fileTypeID == 13 && cItem.voiceController != null)
currentWaveBubble(context, cItem)
currentWaveBubble(context, cItem),
if (fileTypeID == 16)
showVideoThumb(context, cItem)
else
Row(
children: [
if (fileTypeID == 1 ||
fileTypeID == 5 ||
fileTypeID == 7 ||
fileTypeID == 6 ||
fileTypeID == 8
// || fileTypeID == 2
)
fileTypeID == 5 ||
fileTypeID == 7 ||
fileTypeID == 6 ||
fileTypeID == 8
// || fileTypeID == 2
)
SvgPicture.asset(provider.getType(fileTypeName ?? ""),
height: 30,
width: 22,
@ -279,12 +285,12 @@ class GroupChatBubble extends StatelessWidget {
textDirection: provider.getTextDirection(cItem.contant ?? ""),
child: (cItem.contant ?? "").toText12().expanded),
if (fileTypeID == 1 ||
fileTypeID == 5 ||
fileTypeID == 7 ||
fileTypeID == 6 ||
fileTypeID == 8
//|| fileTypeID == 2
)
fileTypeID == 5 ||
fileTypeID == 7 ||
fileTypeID == 6 ||
fileTypeID == 8
//|| fileTypeID == 2
)
const Icon(Icons.remove_red_eye, size: 16)
],
),
@ -422,23 +428,27 @@ class GroupChatBubble extends StatelessWidget {
),
).paddingOnly(bottom: 4),
if (fileTypeID == 13 && cItem.voiceController != null)
recipetWaveBubble(context, cItem)
recipetWaveBubble(context, cItem),
if (fileTypeID == 16)
showVideoThumb(context, cItem)
else
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
cItem.currentUserName!.toText10(
color: Colors.black,
).paddingOnly(bottom: 5),
cItem.currentUserName!
.toText10(
color: Colors.black,
)
.paddingOnly(bottom: 5),
Row(
children: [
if (fileTypeID == 1 ||
fileTypeID == 5 ||
fileTypeID == 7 ||
fileTypeID == 6 ||
fileTypeID == 8
// || fileTypeID == 2
)
fileTypeID == 5 ||
fileTypeID == 7 ||
fileTypeID == 6 ||
fileTypeID == 8
// || fileTypeID == 2
)
SvgPicture.asset(provider.getType(fileTypeName ?? ""),
height: 30,
width: 22,
@ -452,21 +462,23 @@ class GroupChatBubble extends StatelessWidget {
.toText12(color: Colors.white)
.expanded),
if (fileTypeID == 1 ||
fileTypeID == 5 ||
fileTypeID == 7 ||
fileTypeID == 6 ||
fileTypeID == 8
//|| fileTypeID == 2
)
fileTypeID == 5 ||
fileTypeID == 7 ||
fileTypeID == 6 ||
fileTypeID == 8
//|| fileTypeID == 2
)
const Icon(Icons.remove_red_eye,
color: Colors.white, size: 16)
],
),
Align(
alignment: Alignment.topRight,
child: dateTime.toText10(
color: Colors.white.withOpacity(.71),
).paddingOnly(top:5),
child: dateTime
.toText10(
color: Colors.white.withOpacity(.71),
)
.paddingOnly(top: 5),
),
],
),
@ -492,7 +504,7 @@ class GroupChatBubble extends StatelessWidget {
} else {
return FutureBuilder<Uint8List>(
future: ChatApiClient().downloadURL(
fileName: fileName, fileTypeDescription: fileTypeDescription),
fileName: fileName, fileTypeDescription: fileTypeDescription, fileSource:2),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.connectionState != ConnectionState.waiting) {
if (snapshot.data == null) {
@ -557,6 +569,11 @@ class GroupChatBubble extends StatelessWidget {
).circle(5);
}
Widget showVideoThumb(BuildContext context, GetGroupChatHistoryAsync data) {
return LoadVideo(data: data);
}
Widget recipetWaveBubble(
BuildContext context, GetGroupChatHistoryAsync data) {
return Container(
@ -641,3 +658,51 @@ class GroupChatBubble extends StatelessWidget {
);
}
}
class LoadVideo extends StatefulWidget {
final GetGroupChatHistoryAsync data;
const LoadVideo({Key? key, required this.data}) : super(key: key);
@override
State<LoadVideo> createState() => _LoadVideoState();
}
class _LoadVideoState extends State<LoadVideo> {
late VideoPlayerController videoController;
@override
void initState() {
videoController = VideoPlayerController.networkUrl(Uri.parse(
'https://apiderichat.hmg.com/groupattachments/${widget.data.fileTypeResponse?.fileName}'))
..initialize().then((_) {
});
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.all(10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
),
child: AspectRatio(
aspectRatio: videoController.value.aspectRatio,
child: Stack(
alignment: Alignment.bottomCenter,
children: <Widget>[
VideoPlayer(videoController),
Align(
alignment: Alignment.center,
child: Icon(
Icons.play_arrow,
color: Colors.white.withOpacity(.7),
size: 56,
),
)
],
),
));
}
}

@ -113,217 +113,221 @@ class _GroupChatDetailScreenState extends State<GroupChatDetailScreen> {
isDetailedScreen: true,
)
: Column(
children: <Widget>[
SmartRefresher(
enablePullDown: false,
enablePullUp: true,
onLoading: () {
getMoreChat();
},
header: const MaterialClassicHeader(
color: MyColors.gradiantEndColor,
children: <Widget>[
SmartRefresher(
enablePullDown: false,
enablePullUp: true,
onLoading: () {
getMoreChat();
},
header: const MaterialClassicHeader(
color: MyColors.gradiantEndColor,
),
controller: _rc,
reverse: true,
child: ListView.separated(
controller: m.scrollController,
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
reverse: true,
itemCount: m.groupChatHistory.length,
padding: const EdgeInsets.all(21),
separatorBuilder: (BuildContext cxt, int index) => 8.height,
itemBuilder: (BuildContext context, int i) {
return SwipeTo(
iconColor: MyColors.lightGreenColor,
child: GroupChatBubble(
dateTime: m.groupChatHistory[i].createdDate!,
cItem: m.groupChatHistory[i],
),
controller: _rc,
reverse: true,
child: ListView.separated(
controller: m.scrollController,
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
reverse: true,
itemCount: m.groupChatHistory.length,
padding: const EdgeInsets.all(21),
separatorBuilder: (BuildContext cxt, int index) => 8.height,
itemBuilder: (BuildContext context, int i) {
return SwipeTo(
iconColor: MyColors.lightGreenColor,
child: GroupChatBubble(
dateTime: m.groupChatHistory[i].createdDate!,
cItem: m.groupChatHistory[i],
),
onRightSwipe: (val) {
m.groupChatReply(
m.groupChatHistory[i],
);
},
).onPress(() async {
logger.w(m.userChatHistory[i].toJson());
if (m.userChatHistory[i].fileTypeResponse != null && m.userChatHistory[i].fileTypeId != null) {
if (m.userChatHistory[i].fileTypeId! == 1 ||
m.userChatHistory[i].fileTypeId! == 5 ||
m.userChatHistory[i].fileTypeId! == 7 ||
m.userChatHistory[i].fileTypeId! == 6 ||
m.userChatHistory[i].fileTypeId! == 8
// || m.userChatHistory[i].fileTypeId! == 2
) {
m.getChatMedia(context,
fileTypeName: m.userChatHistory[i].fileTypeResponse!.fileTypeName ?? "", fileTypeID: m.userChatHistory[i].fileTypeId!, fileName: m.userChatHistory[i].contant!);
}
}
});
},
),
).expanded,
if (m.isReplyMsg)
SizedBox(
height: 82,
onRightSwipe: (val) {
m.groupChatReply(
m.groupChatHistory[i],
);
},
).onPress(() async {
logger.w(m.groupChatHistory[i].toJson());
if (m.groupChatHistory[i].fileTypeResponse != null && m.groupChatHistory[i].fileTypeId != null) {
if (m.groupChatHistory[i].fileTypeId! == 1 ||
m.groupChatHistory[i].fileTypeId! == 5 ||
m.groupChatHistory[i].fileTypeId! == 7 ||
m.groupChatHistory[i].fileTypeId! == 6 ||
m.groupChatHistory[i].fileTypeId! == 8
|| m.groupChatHistory[i].fileTypeId! == 16
) {
m.getChatMedia(context,
fileTypeName: m.groupChatHistory[i].fileTypeResponse!.fileTypeName ?? "", fileTypeID: m.groupChatHistory[i].fileTypeId!, fileName: m.groupChatHistory[i].contant!,fileSource: 2);
}
}
});
},
),
).expanded,
if (m.isReplyMsg)
SizedBox(
height: 82,
child: Row(
children: <Widget>[
Container(height: 82, color: MyColors.textMixColor, width: 6),
Container(
color: MyColors.darkTextColor.withOpacity(0.10),
padding: const EdgeInsets.only(top: 11, left: 14, bottom: 14, right: 21),
child: Row(
children: <Widget>[
Container(height: 82, color: MyColors.textMixColor, width: 6),
Container(
color: MyColors.darkTextColor.withOpacity(0.10),
padding: const EdgeInsets.only(top: 11, left: 14, bottom: 14, right: 21),
child: Row(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(AppState().chatDetails!.response!.userName == m.groupChatReplyData.first.currentUserName.toString()
? "You"
: m.groupChatReplyData.first.currentUserName.toString().replaceAll(".", " "))
.toText14(color: MyColors.lightGreenColor),
(m.groupChatReplyData.isNotEmpty ? m.groupChatReplyData.first.contant! : "").toText12(color: MyColors.grey71Color, maxLine: 2)
],
).expanded,
12.width,
if (m.isReplyMsg && m.groupChatReplyData.isNotEmpty) showReplyImage(m.groupChatReplyData, m),
12.width,
const Icon(Icons.cancel, size: 23, color: MyColors.grey7BColor).onPress(m.closeMe),
],
),
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(AppState().chatDetails!.response!.userName == m.groupChatReplyData.first.currentUserName.toString()
? "You"
: m.groupChatReplyData.first.currentUserName.toString().replaceAll(".", " "))
.toText14(color: MyColors.lightGreenColor),
(m.groupChatReplyData.isNotEmpty ? m.groupChatReplyData.first.contant! : "").toText12(color: MyColors.grey71Color, maxLine: 2)
],
).expanded,
12.width,
if (m.isReplyMsg && m.groupChatReplyData.isNotEmpty) showReplyImage(m.groupChatReplyData, m),
12.width,
const Icon(Icons.cancel, size: 23, color: MyColors.grey7BColor).onPress(m.closeMe),
],
),
),
if (m.isAttachmentMsg && m.sFileType == ".png" || m.sFileType == ".jpeg" || m.sFileType == ".jpg")
SizedBox(height: 200, width: double.infinity, child: Image.file(m.selectedFile, fit: BoxFit.cover)).paddingOnly(left: 21, right: 21, top: 21),
const Divider(height: 1, color: MyColors.lightGreyEFColor),
if (m.isRecoding)
Column(
children: <Widget>[
Row(
children: [
Text(m.buildTimer()).paddingAll(10),
if (m.isRecoding && m.isPlaying)
WaveBubble(
playerController: m.playerController,
isPlaying: m.playerController.playerState == PlayerState.playing,
onTap: () {},
).expanded
else
AudioWaveforms(
waveStyle: const WaveStyle(
waveColor: MyColors.lightGreenColor,
middleLineColor: Colors.transparent,
extendWaveform: true,
showBottom: true,
showTop: true,
waveThickness: 2,
showMiddleLine: false,
middleLineThickness: 0,
),
padding: const EdgeInsets.all(5),
shouldCalculateScrolledPosition: false,
margin: EdgeInsets.zero,
size: const Size(double.infinity, 30.0),
recorderController: m.recorderController,
backgroundColor: Colors.white,
).expanded,
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Icon(
Icons.delete_outlined,
size: 26,
color: MyColors.lightGreenColor,
).paddingAll(10).onPress(() {
m.deleteRecoding();
}),
SvgPicture.asset("assets/icons/chat/chat_send_icon.svg", height: 26, width: 26)
.onPress(
() => m.sendGroupChatMessage(context,
targetUserId: params!.groupChatDetails!.groupId!,
userStatus: 0,
userEmail: "",
targetUserName: params!.groupChatDetails!.groupName!,
userList: params!.groupChatDetails!.groupUserList!),
)
.paddingOnly(right: 21),
],
).expanded,
],
),
),
if (m.isAttachmentMsg && m.sFileType == ".png" || m.sFileType == ".jpeg" || m.sFileType == ".jpg")
SizedBox(height: 200, width: double.infinity, child: Image.file(m.selectedFile, fit: BoxFit.cover)).paddingOnly(left: 21, right: 21, top: 21),
const Divider(height: 1, color: MyColors.lightGreyEFColor),
if (m.isRecoding)
Column(
children: <Widget>[
Row(
children: [
Text(m.buildTimer()).paddingAll(10),
if (m.isRecoding && m.isPlaying)
WaveBubble(
playerController: m.playerController,
isPlaying: m.playerController.playerState == PlayerState.playing,
onTap: () {},
).expanded
else
AudioWaveforms(
waveStyle: const WaveStyle(
waveColor: MyColors.lightGreenColor,
middleLineColor: Colors.transparent,
extendWaveform: true,
showBottom: true,
showTop: true,
waveThickness: 2,
showMiddleLine: false,
middleLineThickness: 0,
),
padding: const EdgeInsets.all(5),
shouldCalculateScrolledPosition: false,
margin: EdgeInsets.zero,
size: const Size(double.infinity, 30.0),
recorderController: m.recorderController,
backgroundColor: Colors.white,
).expanded,
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Icon(
Icons.delete_outlined,
size: 26,
color: MyColors.lightGreenColor,
).paddingAll(10).onPress(() {
m.deleteRecoding();
}),
SvgPicture.asset("assets/icons/chat/chat_send_icon.svg", height: 26, width: 26)
.onPress(
() => m.sendGroupChatMessage(context,
targetUserId: params!.groupChatDetails!.groupId!,
userStatus: 0,
userEmail: "",
targetUserName: params!.groupChatDetails!.groupName!,
userList: params!.groupChatDetails!.groupUserList!
),
)
.paddingOnly(right: 21),
],
),
],
).objectContainerView(disablePadding: true, radius: 0),
if (!m.isRecoding)
Row(
children: [
CustomAutoDirection(
onDirectionChange: (bool isRTL) => m.onDirectionChange(isRTL),
text: m.msgText,
child: TextField(
// textDirection: m.textDirection,
controller: m.message,
decoration: InputDecoration(
hintTextDirection: m.textDirection,
hintText: m.isAttachmentMsg ? m.selectedFile.path.split("/").last : LocaleKeys.typeheretoreply.tr(),
hintStyle: TextStyle(color: m.isAttachmentMsg ? MyColors.darkTextColor : MyColors.grey98Color, fontSize: 14),
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
filled: true,
fillColor: MyColors.white,
contentPadding: const EdgeInsets.only(
left: 21,
top: 20,
bottom: 20,
),
],
).objectContainerView(disablePadding: true, radius: 0),
if (!m.isRecoding)
prefixIconConstraints: const BoxConstraints(),
prefixIcon: m.sFileType.isNotEmpty
? SvgPicture.asset(m.getType(m.sFileType), height: 30, width: 22, alignment: Alignment.center, fit: BoxFit.cover).paddingOnly(left: 21, right: 15)
: null,
),
onChanged: (String val) {
m.inputBoxDirection(val);
m.groupTypingInvoke(groupDetails: params!.groupChatDetails!, groupId: params!.groupChatDetails!.groupId!);
},
).expanded,
),
if (m.sFileType.isNotEmpty)
Row(
children: [
CustomAutoDirection(
onDirectionChange: (bool isRTL) => m.onDirectionChange(isRTL),
text: m.msgText,
child: TextField(
// textDirection: m.textDirection,
controller: m.message,
decoration: InputDecoration(
hintTextDirection: m.textDirection,
hintText: m.isAttachmentMsg ? m.selectedFile.path.split("/").last : LocaleKeys.typeheretoreply.tr(),
hintStyle: TextStyle(color: m.isAttachmentMsg ? MyColors.darkTextColor : MyColors.grey98Color, fontSize: 14),
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
filled: true,
fillColor: MyColors.white,
contentPadding: const EdgeInsets.only(
left: 21,
top: 20,
bottom: 20,
),
prefixIconConstraints: const BoxConstraints(),
prefixIcon: m.sFileType.isNotEmpty
? SvgPicture.asset(m.getType(m.sFileType), height: 30, width: 22, alignment: Alignment.center, fit: BoxFit.cover).paddingOnly(left: 21, right: 15)
: null,
),
onChanged: (String val) {
m.inputBoxDirection(val);
m.groupTypingInvoke(groupDetails: params!.groupChatDetails!, groupId: params!.groupChatDetails!.groupId!);
children: <Widget>[
const Icon(Icons.cancel, size: 15, color: MyColors.redA3Color).paddingOnly(right: 5),
("Clear").toText11(color: MyColors.redA3Color, isUnderLine: true).paddingOnly(left: 0),
],
).onPress(() => m.removeAttachment()).paddingOnly(right: 15),
if (m.sFileType.isEmpty)
RotationTransition(
turns: const AlwaysStoppedAnimation(45 / 360),
child: const Icon(Icons.attach_file_rounded, size: 26, color: MyColors.grey3AColor).onPress(
() => {
m.selectImageToUpload(context)
},
).expanded,
),
).paddingOnly(right: 15),
const Icon(
Icons.mic,
color: MyColors.lightGreenColor,
).paddingOnly(right: 15).onPress(() {
m.startRecoding(context);
}),
SvgPicture.asset("assets/icons/chat/chat_send_icon.svg", height: 26, width: 26)
.onPress(
() =>m.sendGroupChatMessage(context,
targetUserId: params!.groupChatDetails!.groupId!,
userStatus: 0,
userEmail: "",
targetUserName: params!.groupChatDetails!.groupName!,
userList: params!.groupChatDetails!.groupUserList!
),
if (m.sFileType.isNotEmpty)
Row(
children: <Widget>[
const Icon(Icons.cancel, size: 15, color: MyColors.redA3Color).paddingOnly(right: 5),
("Clear").toText11(color: MyColors.redA3Color, isUnderLine: true).paddingOnly(left: 0),
],
).onPress(() => m.removeAttachment()).paddingOnly(right: 15),
if (m.sFileType.isEmpty)
RotationTransition(
turns: const AlwaysStoppedAnimation(45 / 360),
child: const Icon(Icons.attach_file_rounded, size: 26, color: MyColors.grey3AColor).onPress(
() => {m.selectImageToUpload(context)},
),
).paddingOnly(right: 15),
const Icon(
Icons.mic,
color: MyColors.lightGreenColor,
).paddingOnly(right: 15).onPress(() {
m.startRecoding(context);
}),
SvgPicture.asset("assets/icons/chat/chat_send_icon.svg", height: 26, width: 26)
.onPress(
() => m.sendGroupChatMessage(context,
targetUserId: params!.groupChatDetails!.groupId!,
userStatus: 0,
userEmail: "",
targetUserName: params!.groupChatDetails!.groupName!,
userList: params!.groupChatDetails!.groupUserList!),
)
.paddingOnly(right: 21),
],
).objectContainerView(disablePadding: true, radius: 0),
)
.paddingOnly(right: 21),
],
));
).objectContainerView(disablePadding: true, radius: 0),
],
));
},
),
),
@ -351,7 +355,7 @@ class _GroupChatDetailScreenState extends State<GroupChatDetailScreen> {
}
void makeCall({required String callType}) async {
// callPro.initCallListeners();
callPro.initCallListeners(context: context);
print("================== Make call Triggered ============================");
// Map<String, dynamic> json = {
// "callerID": AppState().chatDetails!.response!.id!.toString(),

@ -18,6 +18,9 @@ import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/chat/incoming_call_model.dart';
import 'package:mohem_flutter_app/models/itg/itg_main_response.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/models/privilege_list_model.dart';
import 'package:mohem_flutter_app/provider/chat_call_provider.dart';
@ -36,6 +39,7 @@ 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';
import 'package:http/http.dart' as http;
class DashboardScreen extends StatefulWidget {
DashboardScreen({Key? key}) : super(key: key);
@ -209,12 +213,12 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
}
void checkERMChannel() {
data.getITGNotification().then((val) {
data.getITGNotification().then((MohemmItgResponseItem? val) {
if (val!.result!.data != null) {
print("-------------------- Survey ----------------------------");
if (val.result!.data!.notificationType == "Survey") {
DashboardApiClient().getAdvertisementDetail(val.result!.data!.notificationMasterId ?? "").then(
(value) {
(ItgMainRes? value) {
if (value!.mohemmItgResponseItem!.statusCode == 200) {
if (value.mohemmItgResponseItem!.result!.data != null) {
// Navigator.pushNamed(context, AppRoutes.survey, arguments: val.result!.data);
@ -230,13 +234,22 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
} else {
print("------------------------------------------- Ads --------------------");
DashboardApiClient().getAdvertisementDetail(val.result!.data!.notificationMasterId ?? "").then(
(value) {
(ItgMainRes? value) {
if (value!.mohemmItgResponseItem!.statusCode == 200) {
if (value.mohemmItgResponseItem!.result!.data != null) {
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!,
// ),
// ),
// );
}
}
},
@ -250,6 +263,46 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldState,
// appBar: AppBar(
// actions: [
// IconButton(
// onPressed: () {
// data.getITGNotification().then((val) {
// if (val!.result!.data != null) {
// print("-------------------- Survey ----------------------------");
// if (val.result!.data!.notificationType == "Survey") {
// Navigator.pushNamed(context, AppRoutes.survey, arguments: val.result!.data);
// } else {
// print("------------------------------------------- Ads --------------------");
// DashboardApiClient().getAdvertisementDetail(val.result!.data!.notificationMasterId ?? "").then(
// (value) {
// if (value!.mohemmItgResponseItem!.statusCode == 200) {
// if (value.mohemmItgResponseItem!.result!.data != null) {
// 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!,
// // ),
// // ),
// // );
// }
// }
// },
// );
// }
// }
// });
// },
// icon: Icon(Icons.add))
// ],
// ),
body: Column(
children: [
Row(
@ -322,106 +375,106 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
child: Consumer<DashboardProviderModel>(
builder: (BuildContext context, DashboardProviderModel model, Widget? child) {
return (model.isAttendanceTrackingLoading
? GetAttendanceTrackingShimmer()
: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
gradient: const LinearGradient(transform: GradientRotation(.46), begin: Alignment.topRight, end: Alignment.bottomLeft, colors: [
MyColors.gradiantEndColor,
MyColors.gradiantStartColor,
]),
),
child: Stack(
alignment: Alignment.center,
? GetAttendanceTrackingShimmer()
: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
gradient: const LinearGradient(transform: GradientRotation(.46), begin: Alignment.topRight, end: Alignment.bottomLeft, colors: [
MyColors.gradiantEndColor,
MyColors.gradiantStartColor,
]),
),
child: Stack(
alignment: Alignment.center,
children: [
if (model.isTimeRemainingInSeconds == 0) SvgPicture.asset("assets/images/thumb.svg"),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (model.isTimeRemainingInSeconds == 0) SvgPicture.asset("assets/images/thumb.svg"),
Column(
LocaleKeys.markAttendance.tr().toText14(color: Colors.white, isBold: true),
if (model.isTimeRemainingInSeconds == 0) DateTime.now().toString().split(" ")[0].toText12(color: Colors.white),
if (model.isTimeRemainingInSeconds != 0)
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
9.height,
Directionality(
textDirection: ui.TextDirection.ltr,
child: CountdownTimer(
endTime: model.endTime,
onEnd: null,
endWidget: "00:00:00".toText14(color: Colors.white, isBold: true),
textStyle: const TextStyle(color: Colors.white, fontSize: 14, letterSpacing: -0.48, fontWeight: FontWeight.bold),
),
),
LocaleKeys.timeLeftToday.tr().toText12(color: Colors.white),
9.height,
ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(20)),
child: LinearProgressIndicator(
value: model.progress,
minHeight: 8,
valueColor: const AlwaysStoppedAnimation<Color>(Colors.white),
backgroundColor: const Color(0xff196D73),
),
),
],
),
],
).paddingOnly(top: 12, right: 15, left: 12),
),
Row(
children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.markAttendance.tr().toText14(color: Colors.white, isBold: true),
if (model.isTimeRemainingInSeconds == 0) DateTime.now().toString().split(" ")[0].toText12(color: Colors.white),
if (model.isTimeRemainingInSeconds != 0)
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
9.height,
Directionality(
textDirection: ui.TextDirection.ltr,
child: CountdownTimer(
endTime: model.endTime,
onEnd: null,
endWidget: "00:00:00".toText14(color: Colors.white, isBold: true),
textStyle: const TextStyle(color: Colors.white, fontSize: 14, letterSpacing: -0.48, fontWeight: FontWeight.bold),
),
),
LocaleKeys.timeLeftToday.tr().toText12(color: Colors.white),
9.height,
ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(20)),
child: LinearProgressIndicator(
value: model.progress,
minHeight: 8,
valueColor: const AlwaysStoppedAnimation<Color>(Colors.white),
backgroundColor: const Color(0xff196D73),
),
),
],
),
],
).paddingOnly(top: 12, right: 15, left: 12),
),
Row(
children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.checkIn.tr().toText12(color: Colors.white),
(model.attendanceTracking!.pSwipeIn == null ? "--:--" : model.attendanceTracking!.pSwipeIn)
.toString()
.toText14(color: Colors.white, isBold: true),
4.height,
],
).paddingOnly(left: 12, right: 12),
),
Container(
margin: EdgeInsets.only(top: AppState().isArabic(context) ? 6 : 0),
width: 45,
height: 45,
padding: const EdgeInsets.only(left: 10, right: 10),
decoration: BoxDecoration(
color: Color(0xff259EA4),
borderRadius: BorderRadius.only(
bottomRight: AppState().isArabic(context) ? Radius.circular(0) : Radius.circular(15),
bottomLeft: AppState().isArabic(context) ? Radius.circular(15) : Radius.circular(0),
),
),
child: SvgPicture.asset(model.isTimeRemainingInSeconds == 0 ? "assets/images/biometrics.svg" : "assets/images/biometrics.svg"),
).onPress(() {
showMyBottomSheet(
context,
callBackFunc: () {},
child: MarkAttendanceWidget(model, isFromDashboard: true),
);
}),
],
),
LocaleKeys.checkIn.tr().toText12(color: Colors.white),
(model.attendanceTracking!.pSwipeIn == null ? "--:--" : model.attendanceTracking!.pSwipeIn)
.toString()
.toText14(color: Colors.white, isBold: true),
4.height,
],
).paddingOnly(left: 12, right: 12),
),
Container(
margin: EdgeInsets.only(top: AppState().isArabic(context) ? 6 : 0),
width: 45,
height: 45,
padding: const EdgeInsets.only(left: 10, right: 10),
decoration: BoxDecoration(
color: Color(0xff259EA4),
borderRadius: BorderRadius.only(
bottomRight: AppState().isArabic(context) ? Radius.circular(0) : Radius.circular(15),
bottomLeft: AppState().isArabic(context) ? Radius.circular(15) : Radius.circular(0),
),
),
],
),
).onPress(
() {
Navigator.pushNamed(context, AppRoutes.todayAttendance);
},
))
child: SvgPicture.asset(model.isTimeRemainingInSeconds == 0 ? "assets/images/biometrics.svg" : "assets/images/biometrics.svg"),
).onPress(() {
showMyBottomSheet(
context,
callBackFunc: () {},
child: MarkAttendanceWidget(model, isFromDashboard: true),
);
}),
],
),
],
),
],
),
).onPress(
() {
Navigator.pushNamed(context, AppRoutes.todayAttendance);
},
))
.animatedSwither();
},
),
@ -482,48 +535,48 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
return model.isOffersLoading
? const OffersShimmerWidget()
: InkWell(
onTap: () {
navigateToDetails(data.getOffersList[index]);
},
child: SizedBox(
onTap: () {
navigateToDetails(data.getOffersList[index]);
},
child: SizedBox(
width: 73,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
width: 73,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
width: 73,
height: 73,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.all(
Radius.circular(100),
),
border: Border.all(color: MyColors.lightGreyE3Color, width: 1),
),
child: ClipRRect(
borderRadius: const BorderRadius.all(
Radius.circular(50),
),
child: Hero(
tag: "ItemImage" + data.getOffersList[index].offersDiscountId.toString()!,
transitionOnUserGestures: true,
child: Image.network(
data.getOffersList[index].logo ?? "",
fit: BoxFit.contain,
),
),
),
),
4.height,
Expanded(
child: AppState().isArabic(context)
? data.getOffersList[index].titleAr!.toText12(isCenter: true, maxLine: 1)
: data.getOffersList[index].titleEn!.toText12(isCenter: true, maxLine: 1),
height: 73,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.all(
Radius.circular(100),
),
border: Border.all(color: MyColors.lightGreyE3Color, width: 1),
),
child: ClipRRect(
borderRadius: const BorderRadius.all(
Radius.circular(50),
),
child: Hero(
tag: "ItemImage" + data.getOffersList[index].offersDiscountId.toString()!,
transitionOnUserGestures: true,
child: Image.network(
data.getOffersList[index].logo ?? "",
fit: BoxFit.contain,
),
],
),
),
),
);
4.height,
Expanded(
child: AppState().isArabic(context)
? data.getOffersList[index].titleAr!.toText12(isCenter: true, maxLine: 1)
: data.getOffersList[index].titleEn!.toText12(isCenter: true, maxLine: 1),
),
],
),
),
);
},
separatorBuilder: (BuildContext cxt, int index) => 8.width,
itemCount: 9),
@ -618,27 +671,27 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
children: [
SvgPicture.asset("assets/icons/chat/chat.svg", color: !checkIfPrivilegedForChat() ? MyColors.lightGreyE3Color : MyColors.grey98Color
// currentIndex == 4
// ? MyColors.grey3AColor
// : cProvider.disableChatForThisUser
// ? MyColors.lightGreyE3Color
// : MyColors.grey98Color,
)
// currentIndex == 4
// ? MyColors.grey3AColor
// : cProvider.disableChatForThisUser
// ? MyColors.lightGreyE3Color
// : MyColors.grey98Color,
)
.paddingAll(4),
Consumer<ChatProviderModel>(
builder: (BuildContext cxt, ChatProviderModel data, Widget? child) {
return !checkIfPrivilegedForChat()
? const SizedBox()
: Positioned(
right: 0,
top: 0,
child: Container(
padding: const EdgeInsets.only(left: 4, right: 4),
alignment: Alignment.center,
decoration: BoxDecoration(color: data.disableChatForThisUser ? MyColors.pinkDarkColor : MyColors.redColor, borderRadius: BorderRadius.circular(17)),
child: data.chatUConvCounter.toString().toText10(color: Colors.white),
),
);
right: 0,
top: 0,
child: Container(
padding: const EdgeInsets.only(left: 4, right: 4),
alignment: Alignment.center,
decoration: BoxDecoration(color: data.disableChatForThisUser ? MyColors.pinkDarkColor : MyColors.redColor, borderRadius: BorderRadius.circular(17)),
child: data.chatUConvCounter.toString().toText10(color: Colors.white),
),
);
},
),
],

@ -98,9 +98,10 @@ class _LoginScreenState extends State<LoginScreen> with WidgetsBindingObserver {
Future<void> setupVoIPCallBacks() async {
if (Platform.isIOS) {
voIPKit.getVoIPToken().then((String? value) async {
print('🎈 example: setupVoIPCallBacks: $value');
print('🎈 example: getVoIPToken: $value');
if (value != null) {
AppState().setiosVoipPlayerID = await ChatApiClient().oneSignalVoip(value);
AppState().setiosVoipPlayerID = await ChatApiClient().oneSignalVoip(value!);
print('🎈 example: OneSignal ID: ${AppState().iosVoipPlayerID}');
}
});
}
@ -413,9 +414,9 @@ class _LoginScreenState extends State<LoginScreen> with WidgetsBindingObserver {
Utils.showLoading(context);
Future.delayed(Duration(seconds: Platform.isIOS ? 3 : 2)).whenComplete(() {
if (!isIncomingCall) {
Utils.hideLoading(context);
if (isAppOpenBySystem!) checkFirebaseToken();
}
Utils.hideLoading(context);
});
}

@ -96,8 +96,7 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
SubmitEITTransactionList submitEITTransactionList = await MyAttendanceApiClient().submitEitTransaction(dESCFLEXCONTEXTCODE, dynamicParams!.dynamicId, values, empID: dynamicParams!.selectedEmp);
Utils.hideLoading(context);
await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen,
arguments: RequestSubmitScreenParams(LocaleKeys.submit.tr(), submitEITTransactionList.pTRANSACTIONID!, submitEITTransactionList.pITEMKEY!, 'eit',
isAttachmentMandatory: dynamicParams!.isAttachmentMandatory));
arguments: RequestSubmitScreenParams(LocaleKeys.submit.tr(), submitEITTransactionList.pTRANSACTIONID!, submitEITTransactionList.pITEMKEY!, 'eit',isAttachmentMandatory: dynamicParams!.isAttachmentMandatory));
if (!AppState().cancelRequestTrancsection) {
return;
}
@ -361,6 +360,10 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
idColName = idColName.parseMonth();
}
}
idColName = Utils.formatDateDefault(idColName!);
// commenting to test
// DateTime date = DateFormat('yyyy-MM-dd').parse(idColName!);
// idColName = DateFormat('yyyy-MM-dd HH:mm:ss').format(date);
}
}

@ -77,7 +77,7 @@ class _OffersAndDiscountsDetailsState extends State<OffersAndDiscountsDetails> {
: getOffersList[0].titleEn!.toText22(isBold: true, color: const Color(0xff2B353E)).center,
Html(
data: AppState().isArabic(context) ? getOffersList[0].descriptionAr! : getOffersList[0].descriptionEn ?? "",
onLinkTap: (String? url, Map<String, String> attributes, _) {
onLinkTap: (String? url, RenderContext context, Map<String, String> attributes, _) {
launchUrl(Uri.parse(url!));
},
),

@ -10,11 +10,14 @@ AppBar AppBarWidget(BuildContext context,
bool showHomeButton = true,
bool showWorkListSettingButton = false,
bool showMemberButton = false,
bool isBackButton =true,
List<Widget>? actions,
void Function()? onHomeTapped,
void Function()? onBackTapped}) {
return AppBar(
automaticallyImplyLeading:false,
leadingWidth: 0,
leading:null,
title: Row(
children: [
GestureDetector(
@ -22,8 +25,8 @@ AppBar AppBarWidget(BuildContext context,
onTap: Feedback.wrapForTap(() {
(onBackTapped == null ? Navigator.maybePop(context) : onBackTapped());
}, context),
child: const Icon(Icons.arrow_back_ios, color: MyColors.darkIconColor),
),
child: const Icon(Icons.arrow_back_ios_new, color: MyColors.darkIconColor),
) ,
4.width,
title.toText24(color: MyColors.darkTextColor, isBold: true).expanded,
],

@ -9,7 +9,7 @@ class AttachmentOptions extends StatelessWidget {
VoidCallback onGalleryTap;
VoidCallback onFilesTap;
bool showFilesOption;
String pickSelection ="";
AttachmentOptions({Key? key, required this.onCameraTap, required this.onGalleryTap, required this.onFilesTap, this.showFilesOption = true}) : super(key: key);
@override
@ -21,6 +21,7 @@ class AttachmentOptions extends StatelessWidget {
children: [
"Upload Attachment".toSectionHeading(),
"Select from gallery or open camera".toText11(weight: FontWeight.w500),
GridView(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 105 / 105, crossAxisSpacing: 9, mainAxisSpacing: 9),
physics: const NeverScrollableScrollPhysics(),

@ -13,6 +13,7 @@ AppBar ChatAppBarWidget(BuildContext context,
{required String title, bool showHomeButton = true, ChatUser? chatUser, bool showTyping = false, List<Widget>? actions, void Function()? onHomeTapped, void Function()? onBackTapped}) {
return AppBar(
leadingWidth: 0,
automaticallyImplyLeading:false,
title: Consumer<ChatProviderModel>(builder: (BuildContext cxt, ChatProviderModel data, Widget? child) {
return Row(
children: [

@ -11,20 +11,25 @@ import 'package:mohem_flutter_app/widgets/bottom_sheets/attachment_options.dart'
import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart';
import 'package:permission_handler/permission_handler.dart';
final ImagePicker picker = ImagePicker();
class ImageOptions {
static void showImageOptionsNew(BuildContext context, bool showFilesOption, Function(String, File) image) {
showMyBottomSheet(
context,
callBackFunc: () {},
child: AttachmentOptions(
showFilesOption: showFilesOption,
onCameraTap: () async {
if (Platform.isAndroid) {
cameraImageAndroid(image);
} else {
File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.camera, imageQuality: 20))?.path ?? "");
String fileName = _image.path;
var bytes = File(fileName).readAsBytesSync();
// XFile? media = await picker.pickMedia();
String? fileName = _image?.path;
var bytes = File(fileName!).readAsBytesSync();
String base64Encode = base64.encode(bytes);
if (base64Encode != null) {
image(base64Encode, _image);
@ -35,7 +40,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 picker.pickMedia())?.path ?? "");
String fileName = _image.path;
var bytes = File(fileName).readAsBytesSync();
String base64Encode = base64.encode(bytes);
@ -146,7 +151,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 picker.pickMedia())?.path ?? "");
String fileName = _image.path;
var bytes = File(fileName).readAsBytesSync();
@ -157,7 +162,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 picker.pickMedia())?.path ?? "");
String fileName = _image.path;
var bytes = File(fileName).readAsBytesSync();
String base64Encode = base64.encode(bytes);

@ -17,7 +17,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
#version: 3.3.01+300040
version: 3.3.6+300046
version: 3.7.7+1
environment:
sdk: ">=2.16.0 <3.0.0"
@ -125,6 +125,7 @@ dependencies:
#todo its for temporary purpose, later will remove this.
dotted_border: ^2.0.0+3
in_app_update: 3.0.0
flutter_ios_voip_kit: ^0.1.0

Loading…
Cancel
Save