diff --git a/lib/constant/colors.dart b/lib/constant/colors.dart index 69c9863..c9b90f2 100644 --- a/lib/constant/colors.dart +++ b/lib/constant/colors.dart @@ -5,4 +5,5 @@ class AppColor { static const Color secondaryColor = Colors.white; static const Color accentColor = Colors.grey; static const Color redColor = Color.fromARGB(255, 199, 56, 46); + static const Color greenColor = Color.fromARGB(255, 43, 225, 43); } diff --git a/lib/constant/links.dart b/lib/constant/links.dart index 635c92b..142f0ab 100644 --- a/lib/constant/links.dart +++ b/lib/constant/links.dart @@ -33,6 +33,7 @@ class AppLink { //-----------------ridessss------------------ static const String addRides = "$ride/rides/add.php"; static const String getRides = "$ride/rides/get.php"; + static const String getRideStatus = "$ride/rides/getRideStatus.php"; static const String updateRides = "$ride/rides/update.php"; static const String deleteRides = "$ride/rides/delete.php"; diff --git a/lib/controller/firebase/firbase_messge.dart b/lib/controller/firebase/firbase_messge.dart index 96cd9c7..7f496c8 100644 --- a/lib/controller/firebase/firbase_messge.dart +++ b/lib/controller/firebase/firbase_messge.dart @@ -8,6 +8,7 @@ import 'package:ride/constant/colors.dart'; import 'package:ride/constant/style.dart'; import 'package:ride/controller/functions/crud.dart'; import 'package:ride/controller/functions/launch.dart'; +import 'package:ride/controller/home/map_page_controller.dart'; import 'package:ride/views/home/profile/promos_passenger_page.dart'; import 'package:ride/views/widgets/elevated_btn.dart'; @@ -206,19 +207,84 @@ class FirebasMessagesController extends GetxController { print(passengerList); print('9999999999999my Apply Ride 999999999999999'); var myList = jsonDecode(passengerList) as List; - - Get.defaultDialog( - barrierDismissible: false, - title: message.notification!.title.toString(), - content: Row( - children: [Text(myList[1].toString())], + Get.snackbar( + 'Captin Applied the Ride for You'.tr, + 'message', + colorText: AppColor.greenColor, + duration: const Duration(seconds: 11), + instantInit: true, + snackPosition: SnackPosition.TOP, + titleText: Text( + 'Applied'.tr, + style: const TextStyle(color: AppColor.redColor), + ), + messageText: Text( + 'Captin Applied the Ride for You'.tr, + style: AppStyle.title, + ), + icon: const Icon(Icons.approval), + shouldIconPulse: true, + maxWidth: double.infinity, + margin: const EdgeInsets.all(16), + padding: const EdgeInsets.all(16), + borderRadius: 8, + borderColor: AppColor.primaryColor, + borderWidth: 2, + backgroundColor: AppColor.secondaryColor, + leftBarIndicatorColor: AppColor.greenColor, + boxShadows: [ + BoxShadow( + color: Colors.black.withOpacity(0.25), + blurRadius: 4, + spreadRadius: 2, + offset: const Offset(0, 4), ), - confirm: MyElevatedButton( - title: 'Ok', - onPressed: () { - // MapController().rideConfirm = true; - }, - )); + ], + backgroundGradient: const LinearGradient( + colors: [AppColor.greenColor, AppColor.accentColor], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + onTap: (GetSnackBar snackBar) { + // Do something when the snackbar is tapped. + // MapController().rideConfirm = false; + // update(); + }, + isDismissible: true, + showProgressIndicator: false, + dismissDirection: DismissDirection.up, + progressIndicatorController: null, + progressIndicatorBackgroundColor: Colors.transparent, + progressIndicatorValueColor: null, + snackStyle: SnackStyle.GROUNDED, + forwardAnimationCurve: Curves.easeInToLinear, + reverseAnimationCurve: Curves.easeInOut, + animationDuration: const Duration(milliseconds: 4000), + barBlur: 8, + overlayBlur: 0, + snackbarStatus: null, + overlayColor: AppColor.primaryColor.withOpacity(0.5), + userInputForm: null, + ); + + // Get.defaultDialog( + // barrierDismissible: false, + // title: message.notification!.title.toString(), + // content: Row( + // children: [Text(myList[1].toString())], + // ), + // confirm: MyElevatedButton( + // title: 'Ok', + // onPressed: () { + // // MapController().rideConfirm = true; + // }, + // ), + // cancel: MyElevatedButton( + // title: 'Cancel', + // onPressed: () { + // Get.back(); + // }, + // )); } else if (message.notification!.title!.contains('Promo')) { Get.to(const PromosPassengerPage()); } @@ -370,9 +436,6 @@ class FirebasMessagesController extends GetxController { } } - // void sendNotificationToManager(String title, body) async { - // // tokens = box.read(BoxName.tokenManager); - // for (var i = 0; i < tokens.length; i++) { // http // .post(Uri.parse('https://fcm.googleapis.com/fcm/send'), diff --git a/lib/controller/home/map_page_controller.dart b/lib/controller/home/map_page_controller.dart index 23401cb..31b609e 100644 --- a/lib/controller/home/map_page_controller.dart +++ b/lib/controller/home/map_page_controller.dart @@ -59,8 +59,12 @@ class MapController extends GetxController { var dataCarsLocationByPassenger; CarLocation? nearestCar; late Timer markerReloadingTimer; - + bool shouldFetch = true; // Flag to determine if fetch should be executed int selectedPassengerCount = 1; + double progress = 0; + int durationTimer = 25; + int remainingTime = 0; + void onChangedPassengerCount(int newValue) { selectedPassengerCount = newValue; update(); @@ -126,9 +130,11 @@ class MapController extends GetxController { } changeConfirmRide() async { - // rideConfirm = true; - // update(); + rideConfirm = true; + shouldFetch = true; + update(); // print('rideConfirm= $rideConfirm'); + var rideId; await getCarsLocationByPassenger(); await CRUD().post(link: AppLink.addRides, payload: { "start_location": '${data[0]['start_address']}', @@ -148,6 +154,7 @@ class MapController extends GetxController { }).then((value) { // print(jsonDecode(value)['message']); // List body = [ + rideId = jsonDecode(value)['message']; List body = [ // '${data[0]['start_address']}', // '${data[0]['end_address']}', @@ -171,29 +178,63 @@ class MapController extends GetxController { dataCarsLocationByPassenger['message'][0]['token'].toString(), body, ); - // FirebasMessagesController().sendNotificationToDriverId( - // 'Order', - // jsonDecode(value)['message'].toString(), - // body[0], - // body[1], - // body[2], - // body[3], - // body[4], - // body[5], - // body[6], - // body[7], - // body[8], - // body[9], - // body[10], - // dataCarsLocationByPassenger['message'][0]['token'].toString(), - // ); - print(dataCarsLocationByPassenger); - print(dataCarsLocationByPassenger['message'][0]['token'].toString()); + // print(dataCarsLocationByPassenger); + // print(dataCarsLocationByPassenger['message'][0]['token'].toString()); }); - + delayAndFetchRideStatus(rideId); + if (shouldFetch == false) { + startTimer(); + } update(); } + void delayAndFetchRideStatus(String rideId) { + Timer(const Duration(seconds: 3), () async { + if (shouldFetch) { + // print('shouldFetch is =$shouldFetch'); + var res = await CRUD() + .get(link: AppLink.getRideStatus, payload: {'order_id': rideId}); + var decod = jsonDecode(res); + // print(' 0000000000000000000000000000000000000000000000000'); + // print(decod['data']); + if (decod['data'].toString() == 'Apply' || + decod['data'].toString() == 'Refused') { + shouldFetch = false; // Stop further fetches + rideConfirm = false; + + update(); + } else { + delayAndFetchRideStatus( + rideId); // Repeat the delay and fetch operation + } + } + }); + startTimer(); + } + + void startTimer() async { + for (int i = 0; i <= durationTimer; i++) { + await Future.delayed(const Duration(seconds: 1)); + progress = i / durationTimer; + remainingTime = durationTimer - i; + + update(); + } + timerEnded(); + } + + void timerEnded() async { + print('Timer ended'); + // refuseOrder(); + } + + Future getRideStatus(int rideId) async { + final response = await CRUD() + .get(link: AppLink.getRideStatus, payload: {'order_id': rideId}); + + return response['status']; + } + Future cancelRide() async { print(rideConfirm); @@ -202,11 +243,13 @@ class MapController extends GetxController { clearpolyline(); data = []; changeCancelRidePageShow(); + rideConfirm = false; update(); } else { clearPlaces(); clearpolyline(); data = []; + rideConfirm = false; changeCancelRidePageShow(); await CRUD().post(link: AppLink.addCancelRide, payload: { @@ -349,7 +392,7 @@ class MapController extends GetxController { Future getCarsLocationByPassenger() async { carsLocationByPassenger = []; LatLngBounds bounds = - calculateBounds(mylocation.latitude, mylocation.longitude, 10); + calculateBounds(mylocation.latitude, mylocation.longitude, 8000); print( 'Southwest: ${bounds.southwest.latitude}, ${bounds.southwest.longitude}'); print( diff --git a/lib/views/home/map_page.dart b/lib/views/home/map_page.dart index 6f133f4..e06dc8c 100644 --- a/lib/views/home/map_page.dart +++ b/lib/views/home/map_page.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; @@ -11,10 +13,13 @@ import 'package:ride/views/widgets/mycircular.dart'; import '../../controller/home/menu_controller.dart'; import 'map_widget.dart/buttom_sheet_map_show.dart'; import 'map_widget.dart/cash_confirm_bottom_page.dart'; +import 'map_widget.dart/driver_card_from_passenger.dart'; +import 'map_widget.dart/left_main_menu_icons.dart'; import 'map_widget.dart/main_bottom_Menu_map.dart'; import 'map_widget.dart/map_menu_widget.dart'; import 'map_widget.dart/menu_map_page.dart'; import 'map_widget.dart/payment_method.page.dart'; +import 'map_widget.dart/timer_for_cancell_trip_from_passenger.dart'; class MapPage extends StatelessWidget { const MapPage({super.key}); @@ -266,104 +271,19 @@ class MapPage extends StatelessWidget { // liteModeEnabled: true, ), ), - GetBuilder( - builder: (controller) => Positioned( - top: 85, - left: 6, - child: Column( - children: [ - AnimatedContainer( - duration: const Duration(microseconds: 200), - width: controller.widthMapTypeAndTrafic, - decoration: BoxDecoration( - border: Border.all(), - color: AppColor.secondaryColor, - borderRadius: BorderRadius.circular(15)), - child: IconButton( - onPressed: () { - controller.changeMapType(); - // Toast.show(context, 'This is a toast message!'); - }, - icon: const Icon( - Icons.satellite_alt, - size: 29, - ), - ), - ), - const SizedBox( - height: 5, - ), - AnimatedContainer( - duration: const Duration(microseconds: 200), - width: controller.widthMapTypeAndTrafic, - decoration: BoxDecoration( - color: AppColor.secondaryColor, - border: Border.all(), - borderRadius: BorderRadius.circular(15)), - child: IconButton( - onPressed: () { - controller.changeMapTraffic(); - // Toast.show(context, 'This is a toast message!'); - }, - icon: const Icon( - Icons.streetview_sharp, - size: 29, - ), - ), - ), - ], - )), - ), + leftMainMenuIcons(), const PickerIconOnMap(), // PickerAnimtionContainerFormPlaces(), const MainBottomMenuMap(), const MapMenuWidget(), const MenuIconMapPageWidget(), buttomSheetMapPage(), - GetBuilder( - builder: ((controller) => controller.rideConfirm - ? Positioned( - top: Get.height * .2, - left: Get.width * .2, - right: Get.width * .2, - child: AnimatedContainer( - duration: const Duration(microseconds: 300), - height: 350, - width: 200, - decoration: BoxDecoration( - border: Border.all(), - color: AppColor.secondaryColor, - borderRadius: BorderRadius.circular(15)), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text( - 'Waiting for Captin ...'.tr, - style: AppStyle.title, - ), - ], - ), - ), - ) - : const SizedBox())), + hexagonClipper(), cancelRidePage(), - GetBuilder( - builder: (controller) => controller.data.isNotEmpty - ? Positioned( - right: 5, - top: 55, - child: GestureDetector( - onTap: () { - controller.changeCancelRidePageShow(); - }, - child: const Icon( - Icons.clear, - size: 30, - ), - )) - : const SizedBox()), + const CancelRidePageShow(), const CashConfirmPageShown(), - const PaymentMethodPage() + const PaymentMethodPage(), + timerForCancellTripFromPassenger(), ], ), ), @@ -371,6 +291,31 @@ class MapPage extends StatelessWidget { } } +class CancelRidePageShow extends StatelessWidget { + const CancelRidePageShow({ + super.key, + }); + + @override + Widget build(BuildContext context) { + return GetBuilder( + builder: (controller) => controller.data.isNotEmpty + ? Positioned( + right: 5, + top: 55, + child: GestureDetector( + onTap: () { + controller.changeCancelRidePageShow(); + }, + child: const Icon( + Icons.clear, + size: 30, + ), + )) + : const SizedBox()); + } +} + class PickerIconOnMap extends StatelessWidget { const PickerIconOnMap({ super.key, diff --git a/lib/views/home/map_widget.dart/driver_card_from_passenger.dart b/lib/views/home/map_widget.dart/driver_card_from_passenger.dart new file mode 100644 index 0000000..c94e6cf --- /dev/null +++ b/lib/views/home/map_widget.dart/driver_card_from_passenger.dart @@ -0,0 +1,131 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../../../constant/colors.dart'; +import '../../../constant/style.dart'; +import '../../../controller/home/map_page_controller.dart'; +import 'hexegone_clipper.dart'; + +GetBuilder hexagonClipper() { + return GetBuilder( + builder: ((controller) => controller.rideConfirm + ? Positioned( + top: Get.height * .2, + left: Get.width * .2, + right: Get.width * .2, + child: ClipPath( + clipper: + HexagonClipper(), // CustomClipper to create a hexagon shape + child: AnimatedContainer( + duration: const Duration(microseconds: 300), + height: 250, + width: 250, + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: AppColor.primaryColor.withOpacity(0.25), + blurRadius: 4, + spreadRadius: 2, + offset: const Offset(0, 4), + ), + BoxShadow( + color: AppColor.accentColor.withOpacity(0.5), + offset: const Offset(-5, -5), + blurRadius: 5, + spreadRadius: 2, + ), + BoxShadow( + color: AppColor.secondaryColor.withOpacity(0.2), + offset: const Offset(5, 5), + blurRadius: 5, + spreadRadius: 2, + ), + ], + gradient: const LinearGradient( + colors: [AppColor.greenColor, AppColor.secondaryColor], + begin: Alignment.topLeft, + end: Alignment.bottomCenter, + ), + border: Border.all(), + color: AppColor.secondaryColor, + borderRadius: BorderRadius.circular(15)), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + 'Waiting for Captin ...'.tr, + style: AppStyle.title, + ), + // IconButton( + // onPressed: () { + // print(controller.dataCarsLocationByPassenger); + // }, + // icon: const Icon(Icons.add), + // ), + Text( + controller.dataCarsLocationByPassenger['message'][0] + ['phone'] + .toString(), + style: AppStyle.title, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Text( + controller.dataCarsLocationByPassenger['message'][0] + ['first_name'] + .toString() + + ' ' + + controller + .dataCarsLocationByPassenger['message'][0] + ['last_name'] + .toString(), + style: AppStyle.title, + ), + Text( + 'Age is '.tr + + controller + .dataCarsLocationByPassenger['message'][0] + ['age'] + .toString(), + style: AppStyle.title, + ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Text( + controller.dataCarsLocationByPassenger['message'][0] + ['make'] + .toString(), + style: AppStyle.title, + ), + Text( + controller.dataCarsLocationByPassenger['message'][0] + ['model'] + .toString(), + style: AppStyle.title, + ), + Text( + controller.dataCarsLocationByPassenger['message'][0] + ['seats'] + .toString(), + style: AppStyle.title, + ), + ], + ), + Text( + controller.dataCarsLocationByPassenger['message'][0] + ['model'] + .toString(), + style: AppStyle.title, + ), + ], + ), + ), + ), + ) + : const SizedBox())); +} diff --git a/lib/views/home/map_widget.dart/hexegone_clipper.dart b/lib/views/home/map_widget.dart/hexegone_clipper.dart new file mode 100644 index 0000000..761981b --- /dev/null +++ b/lib/views/home/map_widget.dart/hexegone_clipper.dart @@ -0,0 +1,36 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; + +class HexagonClipper extends CustomClipper { + @override + Path getClip(Size size) { + final path = Path(); + final height = size.height; + final width = size.width; + final centerX = width / 2; + final centerY = height / 2; + final radius = width / 2; + + const angle = 2 * pi / 10; // Angle between each side of the hexagon + + // Start at the top right vertex of the hexagon + final startX = centerX + radius * cos(0); + final startY = centerY + radius * sin(0); + path.moveTo(startX, startY); + + // Draw the remaining sides of the hexagon + for (int i = 1; i < 10; i++) { + final x = centerX + radius * cos(angle * i); + final y = centerY + radius * sin(angle * i); + path.lineTo(x, y); + } + + path.close(); + + return path; + } + + @override + bool shouldReclip(HexagonClipper oldClipper) => false; +} diff --git a/lib/views/home/map_widget.dart/left_main_menu_icons.dart b/lib/views/home/map_widget.dart/left_main_menu_icons.dart new file mode 100644 index 0000000..172fa9e --- /dev/null +++ b/lib/views/home/map_widget.dart/left_main_menu_icons.dart @@ -0,0 +1,56 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../../../constant/colors.dart'; +import '../../../controller/home/map_page_controller.dart'; + +GetBuilder leftMainMenuIcons() { + return GetBuilder( + builder: (controller) => Positioned( + top: 85, + left: 6, + child: Column( + children: [ + AnimatedContainer( + duration: const Duration(microseconds: 200), + width: controller.widthMapTypeAndTrafic, + decoration: BoxDecoration( + border: Border.all(), + color: AppColor.secondaryColor, + borderRadius: BorderRadius.circular(15)), + child: IconButton( + onPressed: () { + controller.changeMapType(); + // Toast.show(context, 'This is a toast message!'); + }, + icon: const Icon( + Icons.satellite_alt, + size: 29, + ), + ), + ), + const SizedBox( + height: 5, + ), + AnimatedContainer( + duration: const Duration(microseconds: 200), + width: controller.widthMapTypeAndTrafic, + decoration: BoxDecoration( + color: AppColor.secondaryColor, + border: Border.all(), + borderRadius: BorderRadius.circular(15)), + child: IconButton( + onPressed: () { + controller.changeMapTraffic(); + // Toast.show(context, 'This is a toast message!'); + }, + icon: const Icon( + Icons.streetview_sharp, + size: 29, + ), + ), + ), + ], + )), + ); +} diff --git a/lib/views/home/map_widget.dart/timer_for_cancell_trip_from_passenger.dart b/lib/views/home/map_widget.dart/timer_for_cancell_trip_from_passenger.dart new file mode 100644 index 0000000..94a179b --- /dev/null +++ b/lib/views/home/map_widget.dart/timer_for_cancell_trip_from_passenger.dart @@ -0,0 +1,35 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../../../constant/style.dart'; +import '../../../controller/home/map_page_controller.dart'; + +GetBuilder timerForCancellTripFromPassenger() { + return GetBuilder( + builder: (controller) { + final isNearEnd = + controller.remainingTime <= 5; // Define a threshold for "near end" + + return controller.shouldFetch == false + ? Positioned( + bottom: Get.height * .3, + left: Get.width * .05, + child: Stack( + alignment: Alignment.center, + children: [ + CircularProgressIndicator( + value: controller.progress, + // Set the color based on the "isNearEnd" condition + color: isNearEnd ? Colors.red : Colors.blue, + ), + Text( + '${controller.remainingTime}', + style: AppStyle.number, + ), + ], + ), + ) + : const SizedBox(); + }, + ); +} diff --git a/lib/views/orderCaptin/order_request_page.dart b/lib/views/orderCaptin/order_request_page.dart index 60d3176..6690c0e 100644 --- a/lib/views/orderCaptin/order_request_page.dart +++ b/lib/views/orderCaptin/order_request_page.dart @@ -170,6 +170,7 @@ class OrderRequestPage extends StatelessWidget { // box.read(BoxName.tokenDriver).toString(), bodyToPassenger, ); + Get.back(); }, ), GetBuilder( diff --git a/pubspec.lock b/pubspec.lock index 147d183..4df6eaa 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: "5dce45a06d386358334eb1689108db6455d90ceb0d75848d5f4819283d4ee2b8" + sha256: "1a5e13736d59235ce0139621b4bbe29bc89839e202409081bc667eb3cd20674c" url: "https://pub.dev" source: hosted - version: "1.3.4" + version: "1.3.5" animated_text_kit: dependency: "direct main" description: @@ -165,10 +165,10 @@ packages: dependency: "direct main" description: name: firebase_core - sha256: "2e9324f719e90200dc7d3c4f5d2abc26052f9f2b995d3b6626c47a0dfe1c8192" + sha256: c78132175edda4bc532a71e01a32964e4b4fcf53de7853a422d96dac3725f389 url: "https://pub.dev" source: hosted - version: "2.15.0" + version: "2.15.1" firebase_core_platform_interface: dependency: transitive description: @@ -181,34 +181,34 @@ packages: dependency: transitive description: name: firebase_core_web - sha256: "0fd5c4b228de29b55fac38aed0d9e42514b3d3bd47675de52bf7f8fccaf922fa" + sha256: "4cf4d2161530332ddc3c562f19823fb897ff37a9a774090d28df99f47370e973" url: "https://pub.dev" source: hosted - version: "2.6.0" + version: "2.7.0" firebase_messaging: dependency: "direct main" description: name: firebase_messaging - sha256: "8ac91d83a028eef050de770f1dc98421e215714d245f34de7b154d436676fbd0" + sha256: "6c1a2a047d6f165b7c5f947467ac5138731a2af82c7af1c12d691dbb834f6b73" url: "https://pub.dev" source: hosted - version: "14.6.5" + version: "14.6.7" firebase_messaging_platform_interface: dependency: transitive description: name: firebase_messaging_platform_interface - sha256: b2995e3640efb646e9ebf0e2fa50dea84895f0746a31d7e3af0e5e009a533a1a + sha256: bcba58d28f8cda607a323240c6d314c2c62b62ebfbb0f2d704ebefef07b52b5f url: "https://pub.dev" source: hosted - version: "4.5.4" + version: "4.5.6" firebase_messaging_web: dependency: transitive description: name: firebase_messaging_web - sha256: "5d8446a28339124a2cb4f57a6ca454a3aca7d0c5c0cdfa5707afb192f7c830a7" + sha256: "962d09ec9dfa486cbbc218258ad41e8ec7997a2eba46919049496e1cafd960c5" url: "https://pub.dev" source: hosted - version: "3.5.4" + version: "3.5.6" flutter: dependency: "direct main" description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index 8679e2d..cf8829e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -12,7 +12,7 @@ dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.2 - firebase_messaging: ^14.6.5 + firebase_messaging: ^14.6.7 firebase_core: ^2.15.0 flutter_local_notifications: ^15.1.0+1 google_maps_flutter: ^2.4.0