This commit is contained in:
Hamza Aleghwairyeen
2024-04-23 16:16:03 +03:00
parent f2ed2736dc
commit 1c7afbb16d
14 changed files with 1599 additions and 1145 deletions

View File

@@ -95,7 +95,7 @@ class LoginController extends GetxController {
if (jsonDecoeded.isNotEmpty) {
if (jsonDecoeded['status'] == 'success') {
print(jsonDecoeded['data'][0]['verified']);
if (jsonDecoeded['data'][0]['verified'] == '1') {
if (jsonDecoeded['data'][0]['verified'] == 1) {
box.write(BoxName.passengerID, jsonDecoeded['data'][0]['id']);
box.write(BoxName.email, jsonDecoeded['data'][0]['email']);
box.write(

View File

@@ -0,0 +1,119 @@
import 'dart:io';
import 'package:SEFER/controller/home/map_passenger_controller.dart';
// import 'package:flutter_sound/flutter_sound.dart';
import 'package:path_provider/path_provider.dart';
import 'package:get/get.dart';
import 'package:just_audio/just_audio.dart';
import 'package:record/record.dart';
class AudioRecorderController extends GetxController {
AudioPlayer audioPlayer = AudioPlayer();
AudioRecorder recorder = AudioRecorder();
bool isRecording = false;
String filePath = '';
String? selectedFilePath;
double currentPosition = 0;
double totalDuration = 0;
String? selectedFile;
Future<void> startRecording() async {
final bool isPermissionGranted = await recorder.hasPermission();
if (!isPermissionGranted) {
// RecordingPermissionException('l');
print('sss');
return;
}
final directory = await getApplicationDocumentsDirectory();
// Generate a unique file name using the current timestamp
String fileName =
'${DateTime.now().year}-${DateTime.now().month}-${DateTime.now().day}_${Get.find<MapPassengerController>().rideId}.m4a';
filePath = '${directory.path}/$fileName';
// Define the configuration for the recording
const config = RecordConfig(
// Specify the format, encoder, sample rate, etc., as needed
encoder: AudioEncoder.aacLc, // For example, using AAC codec
sampleRate: 44100, // Sample rate
bitRate: 128000, // Bit rate
);
// Start recording to file with the specified configuration
await recorder.start(config, path: filePath);
isRecording = true;
update();
}
Future<void> stopRecording() async {
final path = await recorder.stop();
print(path);
isRecording = false;
update();
}
Future<void> playRecording() async {
if (filePath != null) {
await audioPlayer.setFilePath(filePath!);
totalDuration = audioPlayer.duration?.inSeconds.toDouble() ?? 0;
audioPlayer.play();
audioPlayer.positionStream.listen((position) {
currentPosition = position.inSeconds.toDouble();
});
selectedFilePath = filePath;
update();
}
}
Future<List<String>> getRecordedFiles() async {
final directory = await getApplicationDocumentsDirectory();
final files = await directory.list().toList();
return files
.map((file) => file.path)
.where((path) => path.endsWith('.m4a'))
.toList();
}
Future<void> playRecordedFile(String filePath) async {
await audioPlayer.setFilePath(filePath);
totalDuration = audioPlayer.duration?.inSeconds.toDouble() ?? 0;
audioPlayer.play();
audioPlayer.positionStream.listen((position) {
currentPosition = position.inSeconds.toDouble();
});
update();
}
Future<void> deleteRecordedFile(String filePath) async {
final file = File(filePath);
if (await file.exists()) {
await file.delete();
print('File deleted: $filePath');
await getRecordedFiles();
} else {
print('File not found: $filePath');
}
}
Future<void> deleteAllRecordedFiles() async {
final directory = await getApplicationDocumentsDirectory();
final files = await directory.list().toList();
for (final file in files) {
if (file.path.endsWith('.m4a')) {
await deleteRecordedFile(file.path);
}
}
}
@override
void onClose() {
audioPlayer.dispose();
recorder.dispose();
super.onClose();
}
}

View File

@@ -1,160 +0,0 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_sound/flutter_sound.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import '../home/map_passenger_controller.dart';
class AudioController extends GetxController {
final recorder = FlutterSoundRecorder();
bool isRecording = false;
@override
void onInit() {
super.onInit();
initRecorder();
}
Future<void> initRecorder() async {
final status = await Permission.microphone.request();
if (status != PermissionStatus.granted) {
if (status.isPermanentlyDenied) {
// Handle permission permanently denied
showPermissionDeniedDialog();
} else if (status.isDenied) {
// Handle permission denied
showPermissionDeniedSnackbar();
} else if (status.isRestricted) {
// Handle permission restricted
// showPermissionDeniedSnackbar();
}
return;
}
await recorder.openRecorder();
recorder.setSubscriptionDuration(const Duration(minutes: 50));
}
Future<void> startRecording() async {
if (!recorder.isStopped) {
await recorder.startRecorder();
}
isRecording = true;
update();
}
Future<void> stopRecording() async {
final filePath = await recorder.stopRecorder();
final audioFile = File(filePath!);
print('Recorded file path: $audioFile');
// Now you can send this file to the server
isRecording = false;
update();
}
@override
void onClose() {
recorder.stopRecorder();
super.onClose();
}
void showPermissionDeniedDialog() {
showDialog(
context: Get.context!,
builder: (context) => AlertDialog(
title: const Text('Microphone Permission'),
content:
const Text('Microphone permission is required to record audio.'),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
openAppSettings();
},
child: const Text('Open Settings'),
),
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text('Cancel'),
),
],
),
);
}
void showPermissionDeniedSnackbar() {
Get.snackbar(
'Microphone Permission',
'Microphone permission is required to record audio.',
snackPosition: SnackPosition.BOTTOM,
duration: const Duration(seconds: 5),
mainButton: TextButton(
onPressed: () {
openAppSettings();
},
child: const Text(
'Open Settings',
style: TextStyle(color: Colors.white),
),
),
);
}
}
// import 'package:flutter/material.dart';
// import 'package:flutter_sound/public/flutter_sound_recorder.dart';
// import 'package:get/get.dart';
// // import 'package:flutter_sound/flutter_sound.dart';
// import 'package:permission_handler/permission_handler.dart';
//
// class AudioController extends GetxController {
// final flutterSoundHelper = FlutterSoundHelper();
//
// bool isRecording = false;
//
// Future<void> startRecording() async {
// if (!await flutterSoundHelper.hasPermissions()) {
// await flutterSoundHelper.requestPermissions();
// }
//
// if (!await flutterSoundHelper.hasPermissions()) {
// return;
// }
//
// await flutterSoundHelper.startRecorder();
// isRecording = true;
// }
//
// Future<void> stopRecording() async {
// if (!isRecording) {
// return;
// }
//
// await flutterSoundHelper.stopRecorder();
// isRecording = false;
// }
// }
//
// class FlutterSoundHelper {
// final flutterSound = FlutterSoundRecorder();
//
// Future<bool> hasPermissions() async {
// return await Permission.microphone.isGranted;
// }
//
// Future<void> requestPermissions() async {
// await Permission.microphone.request();
// }
//
// Future<void> startRecorder() async {
// await flutterSound.openRecorder();
// await flutterSound.startRecorder(toFile: 'audio.wav');
// }
//
// Future<void> stopRecorder() async {
// await flutterSound.stopRecorder();
// await flutterSound.closeRecorder();
// }
// }

File diff suppressed because it is too large Load Diff

View File

@@ -98,7 +98,9 @@ class RateController extends GetxController {
await CRUD().post(link: AppLink.addDriversWalletPoints, payload: {
'driverID': Get.find<MapPassengerController>().driverId.toString(),
'paymentID': '${Get.find<MapPassengerController>().rideId}tip',
'amount': (tip * 100).toString(),
'amount': box.read(BoxName.countryCode) == 'Egypt'
? tip.toStringAsFixed(0)
: (tip * 100).toString(),
'paymentMethod': 'visa-tip',
});

View File

@@ -2,120 +2,97 @@ import 'package:SEFER/constant/colors.dart';
import 'package:SEFER/constant/style.dart';
import 'package:SEFER/controller/firebase/firbase_messge.dart';
import 'package:SEFER/controller/home/captin/map_driver_controller.dart';
import 'package:SEFER/controller/functions/call_controller.dart';
import 'package:SEFER/views/widgets/my_scafold.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:SEFER/controller/home/captin/home_captain_controller.dart';
import '../../../../../constant/box_name.dart';
import '../../../../../controller/functions/call_controller.dart';
import '../../../../../main.dart';
class CallPage extends StatelessWidget {
const CallPage({super.key});
@override
Widget build(BuildContext context) {
return MyScafolld(
title: 'Call Page'.tr, isleading: true, body: [callPage()]);
return MyScafolld(title: 'Call Page', isleading: true, body: [callPage()]);
}
}
GetBuilder<HomeCaptainController> callPage() {
CallController callController = Get.put(CallController());
Get.put(MapDriverController());
// callController.initAgoraFull();
callController.initAgoraFull();
return GetBuilder<HomeCaptainController>(
builder: (controller) => Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Padding(
padding: const EdgeInsets.all(15),
child: Container(
decoration: AppStyle.boxDecoration1,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'No SIM card, no problem! Call your driver directly through our app. We use advanced technology to ensure your privacy.'
.tr,
style: AppStyle.title,
),
),
),
),
const SizedBox(
height: 30,
),
Padding(
padding: const EdgeInsets.all(15),
child: Container(
height: 100, width: Get.width,
decoration: AppStyle.boxDecoration1,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
GestureDetector(
onTap: () async {
// await callController.initAgoraFull();
// callController.join();
// FirebaseMessagesController().sendNotificationToPassengerToken(
// 'Call Income',
// 'You have call from driver ${box.read(BoxName.nameDriver)}',
// Get.find<MapDriverController>().tokenPassenger,
// [
// callController.token,
// callController.channelName,
// callController.uid.toString(),
// callController.remoteUid.toString(),
// ],
// );
callController.join();
},
child: Container(
width: 50,
height: 50,
decoration: const BoxDecoration(
shape: BoxShape.circle, color: AppColor.greenColor),
child: const Icon(
Icons.phone,
size: 35,
color: AppColor.secondaryColor,
)),
),
Column(
children: [
Text(callController.status),
Text(Get.find<MapDriverController>()
.passengerName
.toString()),
builder: (controller) => Positioned(
top: Get.height * .2,
child: Container(
height: 100, width: Get.width,
decoration: AppStyle.boxDecoration,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
GestureDetector(
onTap: () async {
// await callController.initAgoraFull();
// callController.join();
FirebaseMessagesController().sendNotificationToPassengerToken(
'Call Income',
'You have call from driver ${box.read(BoxName.nameDriver)}',
Get.find<MapDriverController>().tokenPassenger,
[
callController.token,
callController.channelName,
callController.uid.toString(),
callController.remoteUid.toString(),
],
),
GestureDetector(
onTap: () async {
FirebaseMessagesController()
.sendNotificationToPassengerToken(
'Call End',
'Call End'.tr,
Get.find<MapDriverController>().tokenPassenger,
[],
);
callController.leave();
Get.back();
},
child: Container(
width: 50,
height: 50,
decoration: const BoxDecoration(
shape: BoxShape.circle, color: AppColor.redColor),
child: const Icon(
Icons.phone_disabled_sharp,
size: 35,
color: AppColor.secondaryColor,
)),
)
);
callController.join();
},
child: Container(
width: 50,
height: 50,
decoration: const BoxDecoration(
shape: BoxShape.circle, color: AppColor.greenColor),
child: const Icon(
Icons.phone,
size: 35,
color: AppColor.secondaryColor,
)),
),
Column(
children: [
Text(callController.status),
Text(Get.find<MapDriverController>().passengerName.toString()),
],
),
// ignore: prefer_const_constructors
),
GestureDetector(
onTap: () async {
FirebaseMessagesController().sendNotificationToPassengerToken(
'Call End'.tr,
'Call End',
Get.find<MapDriverController>().tokenPassenger,
[],
);
callController.leave();
Get.back();
},
child: Container(
width: 50,
height: 50,
decoration: const BoxDecoration(
shape: BoxShape.circle, color: AppColor.redColor),
child: const Icon(
Icons.phone_disabled_sharp,
size: 35,
color: AppColor.secondaryColor,
)),
)
],
),
],
// ignore: prefer_const_constructors
),
),
);
}

View File

@@ -4,11 +4,7 @@ import 'package:get/get.dart';
import 'package:SEFER/controller/home/captin/home_captain_controller.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import '../../../../../constant/api_key.dart';
import '../../../../../constant/char_map.dart';
import '../../../../../constant/colors.dart';
import '../../../../../constant/credential.dart';
import '../../../../../controller/functions/audio_recorder_controller.dart';
import '../../../../Rate/ride_calculate_driver.dart';
import '../../../../../controller/functions/location_controller.dart';

View File

@@ -1,10 +1,15 @@
import 'package:SEFER/controller/functions/tts.dart';
import 'package:SEFER/views/widgets/elevated_btn.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:SEFER/constant/colors.dart';
import 'package:SEFER/constant/style.dart';
import 'package:SEFER/views/lang/languages.dart';
import 'package:SEFER/views/widgets/my_scafold.dart';
import 'package:path/path.dart' as path;
import 'package:share/share.dart';
import '../../controller/functions/audio_record1.dart';
import 'profile/passenger_profile_page.dart';
class HomePage extends StatelessWidget {
@@ -18,25 +23,6 @@ class HomePage extends StatelessWidget {
body: [
Column(
children: [
// Padding(
// padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
// child: ListTile(
// title: Text(
// 'Settings'.tr,
// style: AppStyle.headTitle2,
// ),
// subtitle: Text('To change some Settings'.tr),
// trailing: const Icon(
// Icons.arrow_forward_ios,
// size: 30,
// color: AppColor.primaryColor,
// ),
// leading: const Icon(
// Icons.settings,
// color: AppColor.primaryColor,
// ),
// ),
// ),
ListTile(
onTap: () {
Get.to(() => const Language());
@@ -57,7 +43,7 @@ class HomePage extends StatelessWidget {
),
),
ListTile(
leading: const Icon(Icons.place_outlined),
leading: const Icon(Icons.location_city_outlined),
title: Text(
'Change Country'.tr,
style: AppStyle.headTitle2,
@@ -69,6 +55,130 @@ class HomePage extends StatelessWidget {
body: [CountryPickerFromSetting()],
isleading: true)),
),
ListTile(
leading: const Icon(Icons.record_voice_over_outlined),
title: Text(
'Trips recorded'.tr,
style: AppStyle.headTitle2,
),
subtitle: Text('Here recorded trips audio'.tr),
onTap: () async {
Get.defaultDialog(
title: 'Select recorded trip'.tr,
titleStyle: AppStyle.title,
content:
GetBuilder<AudioRecorderController>(builder: (audio) {
return Column(
children: [
FutureBuilder<List<String>>(
future: audio.getRecordedFiles(),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return const CircularProgressIndicator();
} else if (snapshot.hasData) {
final recordedFiles = snapshot.data!;
return DropdownButton<String>(
value: audio.selectedFilePath,
onChanged: (value) {
audio.selectedFilePath = value;
audio.playRecordedFile(value!);
audio.update();
},
items: recordedFiles
.map((file) => DropdownMenuItem<String>(
value: file,
child: Text(path.basename(file)),
))
.toList(),
);
} else {
return Text('Error: ${snapshot.error}');
}
},
),
Slider(
value: audio.currentPosition,
max: audio.totalDuration,
inactiveColor: AppColor.accentColor,
label: audio.currentPosition.toString(),
onChanged: (value) {
audio.currentPosition = value;
// audio.update();
audio.audioPlayer
.seek(Duration(seconds: value.toInt()));
},
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
padding: const EdgeInsets.all(16.0),
color: Colors.grey[200],
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
audio.selectedFilePath != null
? '${'Selected file:'.tr} ${path.basename(audio.selectedFilePath!)}'
: 'No file selected'.tr,
style: AppStyle.subtitle,
),
if (audio.selectedFilePath != null)
IconButton(
icon: const Icon(Icons.share),
onPressed: () {
Share.shareFiles(
[audio.selectedFilePath!]);
},
),
],
),
),
),
IconButton(
onPressed: () async {
Get.defaultDialog(
title: 'Are you sure to delete recorded files'
.tr,
content: Column(
children: [
IconButton(
onPressed: () {
Get.find<TextToSpeechController>()
.speakText(
'this will delete all files from your device'
.tr);
},
icon: const Icon(Icons.headphones),
),
Text(
'this will delete all files from your device'
.tr,
textAlign: TextAlign.center,
style: AppStyle.title,
),
],
),
titleStyle: AppStyle.title,
confirm: MyElevatedButton(
title: 'Delete'.tr,
kolor: AppColor.redColor,
onPressed: () async {
await audio
// .deleteRecordedFile(audio.selectedFilePath!);
.deleteAllRecordedFiles();
Get.back();
Get.back();
}));
},
icon: const Icon(Icons.delete),
),
],
);
}),
);
}),
],
),
],

View File

@@ -167,12 +167,11 @@ class _PassengerCallPageState extends State<PassengerCallPage> {
String statusText;
if (!_isJoined) {
statusText = 'Join a channel'.tr;
} else if (_remoteUid == null) {
statusText = 'Waiting for a remote user to join...'.tr;
} else {
statusText = 'Join a channel';
} else if (_remoteUid == null)
statusText = 'Waiting for a remote user to join...';
else
statusText = 'Connected to remote user, uid:$_remoteUid';
}
return Text(
statusText,

View File

@@ -1,15 +1,10 @@
import 'package:SEFER/controller/payment/payment_controller.dart';
import 'package:SEFER/controller/payment/paymob.dart';
import 'package:SEFER/constant/style.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/main.dart';
import '../../../constant/api_key.dart';
import '../../../constant/char_map.dart';
import 'package:path/path.dart' as path;
import '../../../constant/colors.dart';
import '../../../constant/credential.dart';
import '../../../controller/functions/audio_record1.dart';
import '../../../controller/functions/tts.dart';
import '../../../controller/home/map_passenger_controller.dart';
@@ -96,9 +91,8 @@ GetBuilder<MapPassengerController> leftMainMenuIcons() {
border: Border.all(),
borderRadius: BorderRadius.circular(15)),
child: IconButton(
onPressed: () {
textToSpeechController.speakText(
'''hello this is ${box.read(BoxName.name)}''');
onPressed: () async {
await Get.find<AudioRecorderController>().stopRecording();
},
icon: const Icon(
Icons.voice_chat,
@@ -115,22 +109,21 @@ GetBuilder<MapPassengerController> leftMainMenuIcons() {
borderRadius: BorderRadius.circular(15)),
child: IconButton(
onPressed: () async {
// await PaymentController()
// .payWithPayMobWallet(context, '100', 'EGP', () {});
AC credentials = AC();
String apiKey = AK.payPalSecret;
String convertedStringN = credentials.c(
credentials.c(credentials.c(apiKey, cs), cC), cn);
print('Converted v: $convertedStringN');
// AC credentials = AC();
// String apiKey = AK.payPalSecret;
// String convertedStringN = credentials.c(
// credentials.c(credentials.c(apiKey, cs), cC), cn);
// print('Converted v: $convertedStringN');
// String retrievedStringS = credentials.r(
// credentials.r(credentials.r(convertedStringN, cn), cC),
// cs);
// print('Retrieved String: $retrievedStringS');
// //
// if (retrievedStringS == apiKey) {
// print('same');
// }
String retrievedStringS = credentials.r(
credentials.r(credentials.r(convertedStringN, cn), cC),
cs);
print('Retrieved String: $retrievedStringS');
//
if (retrievedStringS == apiKey) {
print('same');
}
// print(box.read(BoxName.passengerWalletTotal));
// print(box.read(BoxName.name));
// print(box.read(BoxName.phone));
@@ -151,9 +144,12 @@ GetBuilder<MapPassengerController> leftMainMenuIcons() {
// )
// Get.to(() => const CallPage());
// print(box.read(BoxName.lang));
await Get.find<AudioRecorderController>().startRecording();
},
icon: const Icon(
Icons.call,
icon: Icon(
Get.put(AudioRecorderController()).isRecording
? Icons.stop
: Icons.start,
size: 29,
),
),

View File

@@ -6,11 +6,10 @@ import 'package:get/get.dart';
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/controller/profile/profile_controller.dart';
import 'package:SEFER/main.dart';
import 'package:get/get_rx/src/rx_typedefs/rx_typedefs.dart';
import '../../../constant/colors.dart';
import '../../../constant/style.dart';
import '../../../controller/functions/audio_recorder_controller.dart';
import '../../../controller/functions/audio_record1.dart';
import '../../../controller/home/map_passenger_controller.dart';
class RideBeginPassenger extends StatelessWidget {
@@ -21,7 +20,8 @@ class RideBeginPassenger extends StatelessWidget {
@override
Widget build(BuildContext context) {
ProfileController profileController = Get.put(ProfileController());
AudioController audioController = Get.put(AudioController());
AudioRecorderController audioController =
Get.put(AudioRecorderController());
// Get.put(MapPassengerController());
return GetBuilder<MapPassengerController>(builder: (controller) {
if (controller.statusRide == 'Begin' || !controller.statusRideFromStart) {