|
|
|
@ -2,18 +2,20 @@ import 'dart:async';
|
|
|
|
import 'dart:convert';
|
|
|
|
import 'dart:convert';
|
|
|
|
import 'dart:io';
|
|
|
|
import 'dart:io';
|
|
|
|
import 'dart:typed_data';
|
|
|
|
import 'dart:typed_data';
|
|
|
|
|
|
|
|
import 'package:audio_waveforms/audio_waveforms.dart';
|
|
|
|
import 'package:easy_localization/easy_localization.dart';
|
|
|
|
import 'package:easy_localization/easy_localization.dart';
|
|
|
|
import 'package:flutter/cupertino.dart';
|
|
|
|
import 'package:flutter/cupertino.dart';
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
|
|
|
|
import 'package:flutter/services.dart';
|
|
|
|
import 'package:http/http.dart';
|
|
|
|
import 'package:http/http.dart';
|
|
|
|
import 'package:just_audio/just_audio.dart';
|
|
|
|
import 'package:just_audio/just_audio.dart' as JustAudio;
|
|
|
|
import 'package:mohem_flutter_app/api/chat/chat_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/app_state/app_state.dart';
|
|
|
|
|
|
|
|
import 'package:mohem_flutter_app/classes/app_permissions.dart';
|
|
|
|
import 'package:mohem_flutter_app/classes/consts.dart';
|
|
|
|
import 'package:mohem_flutter_app/classes/consts.dart';
|
|
|
|
import 'package:mohem_flutter_app/classes/encryption.dart';
|
|
|
|
import 'package:mohem_flutter_app/classes/encryption.dart';
|
|
|
|
import 'package:mohem_flutter_app/classes/utils.dart';
|
|
|
|
import 'package:mohem_flutter_app/classes/utils.dart';
|
|
|
|
import 'package:mohem_flutter_app/main.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/chat_user_image_model.dart';
|
|
|
|
import 'package:mohem_flutter_app/models/chat/chat_user_image_model.dart';
|
|
|
|
import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart';
|
|
|
|
import 'package:mohem_flutter_app/models/chat/get_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_single_user_chat_list_model.dart';
|
|
|
|
@ -23,6 +25,7 @@ import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart';
|
|
|
|
import 'package:mohem_flutter_app/widgets/image_picker.dart';
|
|
|
|
import 'package:mohem_flutter_app/widgets/image_picker.dart';
|
|
|
|
import 'package:open_file/open_file.dart';
|
|
|
|
import 'package:open_file/open_file.dart';
|
|
|
|
import 'package:path_provider/path_provider.dart';
|
|
|
|
import 'package:path_provider/path_provider.dart';
|
|
|
|
|
|
|
|
import 'package:permission_handler/permission_handler.dart';
|
|
|
|
import 'package:signalr_netcore/hub_connection.dart';
|
|
|
|
import 'package:signalr_netcore/hub_connection.dart';
|
|
|
|
import 'package:signalr_netcore/signalr_client.dart';
|
|
|
|
import 'package:signalr_netcore/signalr_client.dart';
|
|
|
|
import 'package:uuid/uuid.dart';
|
|
|
|
import 'package:uuid/uuid.dart';
|
|
|
|
@ -37,7 +40,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
|
|
|
|
bool isLoading = true;
|
|
|
|
bool isLoading = true;
|
|
|
|
bool isChatScreenActive = false;
|
|
|
|
bool isChatScreenActive = false;
|
|
|
|
int receiverID = 0;
|
|
|
|
int receiverID = 0;
|
|
|
|
|
|
|
|
|
|
|
|
late File selectedFile;
|
|
|
|
late File selectedFile;
|
|
|
|
bool isFileSelected = false;
|
|
|
|
bool isFileSelected = false;
|
|
|
|
String sFileType = "";
|
|
|
|
String sFileType = "";
|
|
|
|
@ -53,9 +55,13 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
|
|
|
|
|
|
|
|
|
|
|
|
Future<void> getUserAutoLoginToken() async {
|
|
|
|
Future<void> getUserAutoLoginToken() async {
|
|
|
|
userLoginToken.UserAutoLoginModel userLoginResponse = await ChatApiClient().getUserLoginToken();
|
|
|
|
userLoginToken.UserAutoLoginModel userLoginResponse = await ChatApiClient().getUserLoginToken();
|
|
|
|
|
|
|
|
print("======================================= Chat Login Token Check =====================================");
|
|
|
|
|
|
|
|
logger.d(userLoginResponse.toJson());
|
|
|
|
|
|
|
|
print("======================================= Chat Login Token Check =====================================");
|
|
|
|
if (userLoginResponse.response != null) {
|
|
|
|
if (userLoginResponse.response != null) {
|
|
|
|
AppState().setchatUserDetails = userLoginResponse;
|
|
|
|
AppState().setchatUserDetails = userLoginResponse;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
|
|
|
|
AppState().setchatUserDetails = userLoginResponse;
|
|
|
|
Utils.showToast(
|
|
|
|
Utils.showToast(
|
|
|
|
userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr",
|
|
|
|
userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr",
|
|
|
|
);
|
|
|
|
);
|
|
|
|
@ -903,7 +909,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void setMsgTune() async {
|
|
|
|
void setMsgTune() async {
|
|
|
|
AudioPlayer player = AudioPlayer();
|
|
|
|
JustAudio.AudioPlayer player = JustAudio.AudioPlayer();
|
|
|
|
await player.setVolume(1.0);
|
|
|
|
await player.setVolume(1.0);
|
|
|
|
String audioAsset = "";
|
|
|
|
String audioAsset = "";
|
|
|
|
if (Platform.isAndroid) {
|
|
|
|
if (Platform.isAndroid) {
|
|
|
|
@ -949,4 +955,133 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
|
|
|
|
logger.d([reciptUser, currentUser]);
|
|
|
|
logger.d([reciptUser, currentUser]);
|
|
|
|
await chatHubConnection.invoke("UserTypingAsync", args: [reciptUser, currentUser]);
|
|
|
|
await chatHubConnection.invoke("UserTypingAsync", args: [reciptUser, currentUser]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Audio Recoding Work
|
|
|
|
|
|
|
|
Timer? _timer;
|
|
|
|
|
|
|
|
int _recodeDuration = 0;
|
|
|
|
|
|
|
|
bool isRecoding = false;
|
|
|
|
|
|
|
|
bool isPause = false;
|
|
|
|
|
|
|
|
bool isPlaying = false;
|
|
|
|
|
|
|
|
String? path;
|
|
|
|
|
|
|
|
String? musicFile;
|
|
|
|
|
|
|
|
late Directory appDirectory;
|
|
|
|
|
|
|
|
late RecorderController recorderController;
|
|
|
|
|
|
|
|
late PlayerController playerController;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////// Audio Recoding Work ////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Future<void> initAudio() async {
|
|
|
|
|
|
|
|
appDirectory = await getApplicationDocumentsDirectory();
|
|
|
|
|
|
|
|
path = "${appDirectory.path}/${AppState().chatDetails!.response!.id}-${DateTime.now().microsecondsSinceEpoch}.aac";
|
|
|
|
|
|
|
|
recorderController = RecorderController()
|
|
|
|
|
|
|
|
..androidEncoder = AndroidEncoder.aac
|
|
|
|
|
|
|
|
..androidOutputFormat = AndroidOutputFormat.mpeg4
|
|
|
|
|
|
|
|
..iosEncoder = IosEncoder.kAudioFormatMPEG4AAC
|
|
|
|
|
|
|
|
..sampleRate = 8000
|
|
|
|
|
|
|
|
..bitRate = 32000;
|
|
|
|
|
|
|
|
playerController = PlayerController();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void disposeAudio() {
|
|
|
|
|
|
|
|
isRecoding = false;
|
|
|
|
|
|
|
|
isPlaying = false;
|
|
|
|
|
|
|
|
isPause = false;
|
|
|
|
|
|
|
|
recorderController.dispose();
|
|
|
|
|
|
|
|
playerController.dispose();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void startRecoding() async {
|
|
|
|
|
|
|
|
PermissionStatus status = await Permission.microphone.request();
|
|
|
|
|
|
|
|
print(status);
|
|
|
|
|
|
|
|
if (status.isDenied == true) {
|
|
|
|
|
|
|
|
startRecoding();
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
recorderController.reset();
|
|
|
|
|
|
|
|
await recorderController.record(path);
|
|
|
|
|
|
|
|
_recodeDuration = 0;
|
|
|
|
|
|
|
|
_startTimer();
|
|
|
|
|
|
|
|
isRecoding = !isRecoding;
|
|
|
|
|
|
|
|
notifyListeners();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void _startTimer() {
|
|
|
|
|
|
|
|
_timer?.cancel();
|
|
|
|
|
|
|
|
_timer = Timer.periodic(const Duration(seconds: 1), (Timer t) {
|
|
|
|
|
|
|
|
_recodeDuration++;
|
|
|
|
|
|
|
|
buildTimer();
|
|
|
|
|
|
|
|
notifyListeners();
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Future<void> pauseRecoding() async {
|
|
|
|
|
|
|
|
isPause = true;
|
|
|
|
|
|
|
|
isPlaying = true;
|
|
|
|
|
|
|
|
recorderController.pause();
|
|
|
|
|
|
|
|
path = await recorderController.stop(false);
|
|
|
|
|
|
|
|
print(path);
|
|
|
|
|
|
|
|
File file = File(path!);
|
|
|
|
|
|
|
|
file.readAsBytesSync();
|
|
|
|
|
|
|
|
await playerController.preparePlayer(file.path, 1.0);
|
|
|
|
|
|
|
|
var tempDuration = _recodeDuration;
|
|
|
|
|
|
|
|
_recodeDuration = tempDuration;
|
|
|
|
|
|
|
|
_timer?.cancel();
|
|
|
|
|
|
|
|
notifyListeners();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void resumeRecoding() {
|
|
|
|
|
|
|
|
isPause = false;
|
|
|
|
|
|
|
|
isPlaying = false;
|
|
|
|
|
|
|
|
isRecoding = true;
|
|
|
|
|
|
|
|
recorderController.record(path);
|
|
|
|
|
|
|
|
_startTimer();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Future<void> deleteRecoding() async {
|
|
|
|
|
|
|
|
print(path);
|
|
|
|
|
|
|
|
_recodeDuration = 0;
|
|
|
|
|
|
|
|
_timer?.cancel();
|
|
|
|
|
|
|
|
// path = await recorderController.stop(false);
|
|
|
|
|
|
|
|
recorderController.reset();
|
|
|
|
|
|
|
|
print(path);
|
|
|
|
|
|
|
|
if (path != null && path!.isNotEmpty) {
|
|
|
|
|
|
|
|
File delFile = File(path!);
|
|
|
|
|
|
|
|
double fileSizeInKB = delFile.lengthSync() / 1024;
|
|
|
|
|
|
|
|
double fileSizeInMB = fileSizeInKB / 1024;
|
|
|
|
|
|
|
|
debugPrint("Deleted file size: ${delFile.lengthSync()}");
|
|
|
|
|
|
|
|
debugPrint("Deleted file size in KB: " + fileSizeInKB.toString());
|
|
|
|
|
|
|
|
debugPrint("Deleted file size in MB: " + fileSizeInMB.toString());
|
|
|
|
|
|
|
|
if (await delFile.exists()) {
|
|
|
|
|
|
|
|
delFile.delete();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
isPause = false;
|
|
|
|
|
|
|
|
isRecoding = false;
|
|
|
|
|
|
|
|
isPlaying = false;
|
|
|
|
|
|
|
|
notifyListeners();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
String buildTimer() {
|
|
|
|
|
|
|
|
String minutes = _formatNum(_recodeDuration ~/ 60);
|
|
|
|
|
|
|
|
String seconds = _formatNum(_recodeDuration % 60);
|
|
|
|
|
|
|
|
return '$minutes : $seconds';
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
String _formatNum(int number) {
|
|
|
|
|
|
|
|
String numberStr = number.toString();
|
|
|
|
|
|
|
|
if (number < 10) {
|
|
|
|
|
|
|
|
numberStr = '0' + numberStr;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return numberStr;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void playRecoding() async {
|
|
|
|
|
|
|
|
isPlaying = true;
|
|
|
|
|
|
|
|
await playerController.startPlayer(finishMode: FinishMode.stop);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void playOrPause() async {
|
|
|
|
|
|
|
|
playerController.playerState == PlayerState.playing ? await playerController.pausePlayer() : playRecoding();
|
|
|
|
|
|
|
|
notifyListeners();
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|