This commit is contained in:
Hamza-Ayed
2023-10-03 16:00:33 +03:00
parent ca59d9e3b7
commit edc3a4348d
12 changed files with 238 additions and 105 deletions

View File

@@ -2,8 +2,6 @@
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<application android:label="SEFER" android:name="${applicationName}" android:icon="@mipmap/launcher_icon"> <application android:label="SEFER" android:name="${applicationName}" android:icon="@mipmap/launcher_icon">
<activity android:name=".MainActivity" android:exported="true" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize"> <activity android:name=".MainActivity" android:exported="true" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as <!-- Specifies an Android theme to apply to this Activity as soon as
@@ -17,12 +15,11 @@
</intent-filter> </intent-filter>
</activity> </activity>
<meta-data android:name="com.google.android.geo.API_KEY" android:value="AIzaSyCyfwRXTwSTLOFQSQgN5p7QZgGJVZnEKq0"/> <meta-data android:name="com.google.android.geo.API_KEY" android:value="AIzaSyCyfwRXTwSTLOFQSQgN5p7QZgGJVZnEKq0"/>
<meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="@string/default_notification_channel_id"/> <meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="@string/default_notification_channel_id"/>
<meta-data android:name="com.android.application.versionCode" android:value="1"/> <meta-data android:name="com.android.application.versionCode" android:value="1"/>
<!-- Don't delete the meta-data below. <!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data android:name="flutterEmbedding" android:value="2"/> <meta-data android:name="flutterEmbedding" android:value="2"/>
</application> </application>
<uses-permission android:name="android.permission.INTERNET"/>
</manifest> </manifest>

View File

@@ -8,6 +8,7 @@ import 'package:ride/constant/colors.dart';
import 'package:ride/constant/style.dart'; import 'package:ride/constant/style.dart';
import 'package:ride/controller/functions/crud.dart'; import 'package:ride/controller/functions/crud.dart';
import 'package:ride/controller/functions/launch.dart'; import 'package:ride/controller/functions/launch.dart';
import 'package:ride/controller/home/captin/map_dirction.dart';
import 'package:ride/controller/home/map_page_controller.dart'; import 'package:ride/controller/home/map_page_controller.dart';
import 'package:ride/views/home/profile/promos_passenger_page.dart'; import 'package:ride/views/home/profile/promos_passenger_page.dart';
import 'package:ride/views/widgets/elevated_btn.dart'; import 'package:ride/views/widgets/elevated_btn.dart';
@@ -18,19 +19,20 @@ import '../../constant/links.dart';
import '../../main.dart'; import '../../main.dart';
import '../../views/orderCaptin/order_request_page.dart'; import '../../views/orderCaptin/order_request_page.dart';
class FirebasMessagesController extends GetxController { class FirebaseMessagesController extends GetxController {
final fcmToken = FirebaseMessaging.instance; final fcmToken = FirebaseMessaging.instance;
List<String> tokens = []; List<String> tokens = [];
List dataTokens = []; List dataTokens = [];
late String driverID; late String driverID;
late String driverToken;
NotificationSettings? notificationSettings; NotificationSettings? notificationSettings;
@override @override
void onInit() async { void onInit() async {
super.onInit(); super.onInit();
// getNotificationSettings(); // getNotificationSettings();
getToken(); // getToken();
await getTokens(); // await getTokens();
} }
Future<void> getNotificationSettings() async { Future<void> getNotificationSettings() async {
@@ -106,6 +108,9 @@ class FirebasMessagesController extends GetxController {
print(myListString); print(myListString);
print('9999999999999myListString999999999999999'); print('9999999999999myListString999999999999999');
var myList = jsonDecode(myListString) as List<dynamic>; var myList = jsonDecode(myListString) as List<dynamic>;
driverToken = myList[14].toString();
update();
print('driverToken==============' + driverToken.toString());
Get.to(() => OrderRequestPage(), arguments: { Get.to(() => OrderRequestPage(), arguments: {
'myListString': myListString, 'myListString': myListString,
'DriverList': myList, 'DriverList': myList,
@@ -117,6 +122,7 @@ class FirebasMessagesController extends GetxController {
print('9999999999999my Apply Ride 999999999999999'); print('9999999999999my Apply Ride 999999999999999');
var myList = jsonDecode(passengerList) as List<dynamic>; var myList = jsonDecode(passengerList) as List<dynamic>;
driverID = myList[2].toString(); driverID = myList[2].toString();
Get.snackbar( Get.snackbar(
'Captin Applied the Ride for You'.tr, 'Captin Applied the Ride for You'.tr,
'message', 'message',
@@ -178,12 +184,15 @@ class FirebasMessagesController extends GetxController {
); );
} else if (message.notification!.title!.contains('Promo')) { } else if (message.notification!.title!.contains('Promo')) {
Get.to(const PromosPassengerPage()); Get.to(const PromosPassengerPage());
} else if (message.notification!.title == ('Ride Begin')) { } else if (message.notification!.title!.contains('BeginTrip')) {
Get.snackbar( // MapDirection mapDirection = Get.find<MapDirection>();
'Trip Begin'.tr, // mapDirection.clearPolyline();
'by Passenger'.tr, print('jjjjjjjjjjjjjjjjjjjjjjjjjjj');
backgroundColor: AppColor.yellowColor, Get.defaultDialog(
title: 'The Ride is Begin'.tr,
backgroundColor: AppColor.greenColor,
); );
MapDirection().clearPolyline();
} }
} }
}); });
@@ -470,9 +479,11 @@ class FirebasMessagesController extends GetxController {
} }
} }
void sendNotificationToDriverId(String title, body, token) async { void sendNotificationToDriverId(
http String title, String body, String token) async {
.post(Uri.parse('https://fcm.googleapis.com/fcm/send'), try {
final response = await http.post(
Uri.parse('https://fcm.googleapis.com/fcm/send'),
headers: <String, String>{ headers: <String, String>{
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Authorization': 'key=${AppCredintials.serverAPI}' 'Authorization': 'key=${AppCredintials.serverAPI}'
@@ -486,11 +497,21 @@ class FirebasMessagesController extends GetxController {
'data': {}, 'data': {},
'priority': 'high', 'priority': 'high',
'to': token, 'to': token,
})) }),
.whenComplete(() {}) );
.catchError((e) {
if (response.statusCode == 200) {
// Notification sent successfully
print('Notification sent successfully');
} else {
// Handle error response
print(
'Failed to send notification. Status code: ${response.statusCode}');
}
} catch (e) {
// Handle other exceptions
print('sendNotification() error: $e'); print('sendNotification() error: $e');
}); }
} }
void sendNotificationToDriverMAP( void sendNotificationToDriverMAP(

View File

@@ -49,8 +49,8 @@ class CRUD {
'Basic ${base64Encode(utf8.encode(AppCredintials.basicAuthCredentials))}', 'Basic ${base64Encode(utf8.encode(AppCredintials.basicAuthCredentials))}',
}, },
); );
print(response.request); // print(response.request);
print(payload); // print(payload);
var jsonData = jsonDecode(response.body); var jsonData = jsonDecode(response.body);
if (response.statusCode == 200) { if (response.statusCode == 200) {

View File

@@ -77,10 +77,10 @@ class LocationController extends GetxController {
: null)!; : null)!;
// Print location details // Print location details
print('Accuracy: ${_locationData.accuracy}'); // print('Accuracy: ${_locationData.accuracy}');
print('Latitude: ${_locationData.latitude}'); // print('Latitude: ${_locationData.latitude}');
print('Longitude: ${_locationData.longitude}'); // print('Longitude: ${_locationData.longitude}');
print('Time: ${_locationData.time}'); // print('Time: ${_locationData.time}');
isLoading = false; isLoading = false;
update(); update();
} }

View File

@@ -1,21 +1,69 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:google_polyline_algorithm/google_polyline_algorithm.dart'; import 'package:google_polyline_algorithm/google_polyline_algorithm.dart';
import 'package:ride/constant/colors.dart'; import 'package:ride/constant/colors.dart';
import 'package:ride/controller/functions/location_controller.dart';
import '../../../constant/credential.dart'; import '../../../constant/credential.dart';
import '../../../constant/links.dart'; import '../../../constant/links.dart';
import '../../functions/crud.dart'; import '../../functions/crud.dart';
class MapDirction extends GetxController { class MapDirection extends GetxController {
bool isLoading = true; bool isLoading = true;
List data = []; List data = [];
LatLngBounds? boundsdata; LatLngBounds? boundsData;
BitmapDescriptor carIcon = BitmapDescriptor.defaultMarker;
final List<LatLng> polylineCoordinates = []; final List<LatLng> polylineCoordinates = [];
List<Polyline> polyLines = []; List<Polyline> polyLines = [];
Set<Marker> markers = {};
getMap(LatLng origin, destination) async { void clearPolyline() {
polyLines = [];
polylineCoordinates.clear();
update();
}
void updateMarker() {
// Remove the existing marker with the ID `MyLocation`.
markers.remove(MarkerId('MyLocation'.tr));
// Add a new marker with the ID `MyLocation` at the current location of the user.
LocationController locationController = Get.find<LocationController>();
markers.add(Marker(
markerId: MarkerId('MyLocation'.tr),
position: locationController.myLocation,
draggable: true,
icon: carIcon,
// infoWindow: const InfoWindow(
// title: 'Time',
// ),
));
// Update the `markers` set and call the `update()` method on the controller to notify the view that the marker position has changed.
update();
// Reload the marker after 3 seconds.
Future.delayed(const Duration(seconds: 3), () {
updateMarker();
});
}
void addCustomCarIcon() {
ImageConfiguration config = ImageConfiguration(
size: Size(Get.width * .6, Get.height * .6),
// scale: 1.0,
);
BitmapDescriptor.fromAssetImage(config, 'assets/images/car.png')
.then((value) {
carIcon = value;
update();
});
}
getMap(String origin, destination) async {
isLoading = false; isLoading = false;
update(); update();
@@ -34,7 +82,16 @@ class MapDirction extends GetxController {
polylineCoordinates.add(LatLng(lat, lng)); polylineCoordinates.add(LatLng(lat, lng));
} }
if (polyLines.isNotEmpty) { if (polyLines.isNotEmpty) {
// clearPolyline(); clearPolyline();
var polyline = Polyline(
polylineId: PolylineId(response["routes"][0]["summary"]),
points: polylineCoordinates,
width: 10,
color: AppColor.blueColor,
);
polyLines.add(polyline);
// rideConfirm = false;
update();
} else { } else {
var polyline = Polyline( var polyline = Polyline(
polylineId: PolylineId(response["routes"][0]["summary"]), polylineId: PolylineId(response["routes"][0]["summary"]),
@@ -43,7 +100,7 @@ class MapDirction extends GetxController {
color: AppColor.blueColor, color: AppColor.blueColor,
); );
// polyLines.add(polyline); polyLines.add(polyline);
// rideConfirm = false; // rideConfirm = false;
update(); update();
} }
@@ -51,6 +108,15 @@ class MapDirction extends GetxController {
@override @override
void onInit() { void onInit() {
// Get the passenger location from the arguments.
String passengerLocation = Get.arguments['passengerLocation'];
String lat = Get.find<LocationController>().myLocation.latitude.toString();
String lng = Get.find<LocationController>().myLocation.longitude.toString();
String origin = '$lat,$lng';
// Set the origin and destination coordinates for the Google Maps directions request.
getMap(origin, passengerLocation);
addCustomCarIcon();
updateMarker();
super.onInit(); super.onInit();
} }
} }

View File

@@ -168,6 +168,7 @@ class MapController extends GetxController {
} }
var rideId; var rideId;
late String driverToken;
int carsOrder = 0; int carsOrder = 0;
changeConfirmRide() async { changeConfirmRide() async {
PaymentController paymentController = Get.find<PaymentController>(); PaymentController paymentController = Get.find<PaymentController>();
@@ -175,6 +176,8 @@ class MapController extends GetxController {
shouldFetch = true; shouldFetch = true;
isBottomSheetShown = false; isBottomSheetShown = false;
timeToPassengerFromDriverAfterApplied = 60; timeToPassengerFromDriverAfterApplied = 60;
driverToken =
dataCarsLocationByPassenger['message'][carsOrder]['token'].toString();
update(); update();
// print('rideConfirm= $rideConfirm'); // print('rideConfirm= $rideConfirm');
@@ -189,7 +192,8 @@ class MapController extends GetxController {
"endtime": durationToAdd.toString(), "endtime": durationToAdd.toString(),
"price": totalPassenger.toString(), "price": totalPassenger.toString(),
"passenger_id": box.read(BoxName.pasengerID).toString(), "passenger_id": box.read(BoxName.pasengerID).toString(),
"driver_id": dataCarsLocationByPassenger['message'][0]['id'].toString(), "driver_id":
dataCarsLocationByPassenger['message'][carsOrder]['id'].toString(),
"status": "waiting", "status": "waiting",
"price_for_driver": totalDriver.toString(), "price_for_driver": totalDriver.toString(),
"price_for_passenger": totalME.toString(), "price_for_passenger": totalME.toString(),
@@ -214,9 +218,10 @@ class MapController extends GetxController {
box.read(BoxName.phone).toString(), box.read(BoxName.phone).toString(),
durationByPassenger.toString(), durationByPassenger.toString(),
distanceByPassenger.toString(), distanceByPassenger.toString(),
paymentController.isWalletChecked.toString() paymentController.isWalletChecked.toString(),
dataCarsLocationByPassenger['message'][carsOrder]['token'].toString(),
]; ];
FirebasMessagesController().sendNotificationToDriverMAP( FirebaseMessagesController().sendNotificationToDriverMAP(
'Order', 'Order',
jsonDecode(value)['message'].toString(), jsonDecode(value)['message'].toString(),
dataCarsLocationByPassenger['message'][carsOrder]['token'].toString(), dataCarsLocationByPassenger['message'][carsOrder]['token'].toString(),
@@ -410,6 +415,7 @@ class MapController extends GetxController {
changeCancelRidePageShow(); changeCancelRidePageShow();
rideConfirm = false; rideConfirm = false;
shouldFetch = false; shouldFetch = false;
timeToPassengerFromDriverAfterApplied = 0;
update(); update();
} else { } else {
clearPlaces(); clearPlaces();
@@ -417,12 +423,13 @@ class MapController extends GetxController {
data = []; data = [];
rideConfirm = false; rideConfirm = false;
shouldFetch = false; shouldFetch = false;
timeToPassengerFromDriverAfterApplied = 0;
changeCancelRidePageShow(); changeCancelRidePageShow();
remainingTime = 25; remainingTime = 25;
update(); update();
await CRUD().post(link: AppLink.addCancelRideFromPassenger, payload: { await CRUD().post(link: AppLink.addCancelRideFromPassenger, payload: {
"driverID": FirebasMessagesController() "driverID": FirebaseMessagesController()
.driverID .driverID
.toString(), // Convert to String .toString(), // Convert to String
"passengerID": "passengerID":

View File

@@ -40,9 +40,9 @@ void main() async {
); );
} }
await FirebasMessagesController().requestFirebaseMessagingPermission(); await FirebaseMessagesController().requestFirebaseMessagingPermission();
// await FirebasMessagesController().getNotificationSettings(); // await FirebasMessagesController().getNotificationSettings();
await FirebasMessagesController().getToken(); await FirebaseMessagesController().getToken();
// await FirebasMessagesController().getTokens(); // await FirebasMessagesController().getTokens();
LocationPermissions().locationPermissions(); LocationPermissions().locationPermissions();
FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler); FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler);

View File

@@ -67,37 +67,27 @@ class TimerToPassengerFromDriver extends StatelessWidget {
? MyElevatedButton( ? MyElevatedButton(
title: 'If you in Car Now. Press Start The Ride', title: 'If you in Car Now. Press Start The Ride',
onPressed: () async { onPressed: () async {
MapController mapController =
Get.find<MapController>();
final firebasMessagesController =
Get.put(FirebasMessagesController());
//todo start the trip and rest all counter ,start new counter of the trip time //todo start the trip and rest all counter ,start new counter of the trip time
await CRUD() await CRUD()
.post(link: AppLink.updateRides, payload: { .post(link: AppLink.updateRides, payload: {
'id': mapController.rideId, 'id': controller.rideId,
'rideTimeStart': DateTime.now().toString(), 'rideTimeStart': DateTime.now().toString(),
'status': 'Applied' 'status': 'Applied'
}); });
mapController.driverArrivePassenger(); controller.driverArrivePassenger();
// Send notification to driver to alert him that trip is begin // Send notification to driver to alert him that trip is begin
firebasMessagesController FirebaseMessagesController()
.sendNotificationToDriverId( .sendNotificationToDriverId(
'Ride Begin', 'BeginTrip',
box.read(BoxName.name).toString(), box.read(BoxName.name).toString(),
mapController controller.driverToken.toString(),
.dataCarsLocationByPassenger['message'][0]
['token']
.toString(),
);
print(mapController
.dataCarsLocationByPassenger['message'][0]
['token']
.toString());
Get.snackbar(
'The Ride is Begin'.tr,
'',
backgroundColor: AppColor.greenColor,
); );
print(controller.driverToken.toString());
// Get.defaultDialog(
// title: 'The Ride is Begin'.tr,
// backgroundColor: AppColor.greenColor,
// );
}) })
: const SizedBox() : const SizedBox()
], ],

View File

@@ -178,7 +178,7 @@ class OrderRequestPage extends StatelessWidget {
box.read(BoxName.tokenDriver).toString(), box.read(BoxName.tokenDriver).toString(),
]; ];
// print(bodyToPassenger); // print(bodyToPassenger);
FirebasMessagesController() FirebaseMessagesController()
.sendNotificanToPassengerToken( .sendNotificanToPassengerToken(
'Apply Ride', 'Apply Ride',
arguments['DriverList'][9].toString(), arguments['DriverList'][9].toString(),
@@ -187,7 +187,9 @@ class OrderRequestPage extends StatelessWidget {
bodyToPassenger, bodyToPassenger,
); );
Get.back(); Get.back();
Get.to(() => PassengerLocationDirection()); Get.to(() => PassengerLocationDirection(), arguments: {
'passengerLocation': myList[0].toString(),
});
}, },
), ),
GetBuilder<OrderRequestController>( GetBuilder<OrderRequestController>(
@@ -222,7 +224,7 @@ class OrderRequestPage extends StatelessWidget {
orderRequestController.refuseOrder( orderRequestController.refuseOrder(
myList[6].toString(), body.toString()); myList[6].toString(), body.toString());
FirebasMessagesController() FirebaseMessagesController()
.sendNotificanToPassengerToken( .sendNotificanToPassengerToken(
'Refused Ride', 'Refused Ride',
arguments['DriverList'][9].toString(), arguments['DriverList'][9].toString(),

View File

@@ -4,30 +4,65 @@ import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:ride/controller/home/captin/map_dirction.dart'; import 'package:ride/controller/home/captin/map_dirction.dart';
import 'package:ride/views/widgets/my_scafold.dart'; import 'package:ride/views/widgets/my_scafold.dart';
import '../../constant/colors.dart';
import '../../controller/functions/location_controller.dart'; import '../../controller/functions/location_controller.dart';
import '../widgets/mycircular.dart'; import '../home/map_widget.dart/passenger_info_window.dart';
import '../home/map_widget.dart/timer_to_passenger_from_driver.dart';
class PassengerLocationDirection extends StatelessWidget { class PassengerLocationDirection extends StatelessWidget {
PassengerLocationDirection({super.key}); PassengerLocationDirection({super.key});
// final LocationController locationController = Get.put(LocationController()); final LocationController locationController = Get.put(LocationController());
// final MapDirection mapDirection = Get.find<MapDirection>();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Get.put(LocationController()); Get.put(MapDirection());
// mapDirection.getMap();//todo get this argument // mapDirection.getMap();//todo get this argument
return MyScafolld( return MyScafolld(
title: 'Map'.tr, title: 'Map'.tr,
body: [ body: [
Padding( Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: GetBuilder<LocationController>( child: GetBuilder<MapDirection>(
builder: (controller) => GoogleMap( builder: (controller) => GoogleMap(
initialCameraPosition: CameraPosition( initialCameraPosition: CameraPosition(
target: controller.myLocation, target: locationController.myLocation,
zoom: 15, zoom: 15,
), ),
)), polylines: {
) Polyline(
zIndex: 2,
consumeTapEvents: true,
geodesic: true,
endCap: Cap.buttCap,
startCap: Cap.buttCap,
visible: true,
polylineId: const PolylineId('route'),
points: controller.polylineCoordinates,
color: AppColor.greenColor,
width: 5,
),
},
markers: {
Marker(
markerId: MarkerId('MyLocation'.tr),
position: locationController.myLocation,
draggable: true,
icon: controller.carIcon,
infoWindow: const InfoWindow(
title: 'Time',
// snippet: controller.durationFromDriverToPassenger
// .toString(),
),
),
},
onCameraMove: (cameraPosition) {
controller.updateMarker();
},
),
),
),
// const TimerToPassengerFromDriver(),
const PassengerInfoWindow()
], ],
isleading: true); isleading: true);
} }

View File

@@ -67,6 +67,7 @@ flutter:
- assets/images/ - assets/images/
- assets/lottie/ - assets/lottie/
- assets/fonts/ - assets/fonts/
- shorebird.yaml
fonts: fonts:
- family: digital-counter-7 - family: digital-counter-7

14
shorebird.yaml Normal file
View File

@@ -0,0 +1,14 @@
# This file is used to configure the Shorebird updater used by your app.
# Learn more at https://docs.shorebird.dev
# This file should be checked into version control.
# This is the unique identifier assigned to your app.
# Your app_id is not a secret and is just used to identify your app
# when requesting patches from Shorebird's servers.
app_id: 8a571d7f-dfbf-4a65-be62-17eed08cbd5c
# auto_update controls if Shorebird should automatically update in the background on launch.
# If auto_update: false, you will need to use package:shorebird_code_push to trigger updates.
# https://pub.dev/packages/shorebird_code_push
# Uncomment the following line to disable automatic updates.
# auto_update: false