11/17/1
This commit is contained in:
@@ -148,8 +148,8 @@ android {
|
|||||||
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
|
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
|
||||||
minSdk = 23
|
minSdk = 23
|
||||||
targetSdk = flutter.targetSdkVersion
|
targetSdk = flutter.targetSdkVersion
|
||||||
versionCode = 94
|
versionCode = 97
|
||||||
versionName = '1.5.94'
|
versionName = '1.5.97'
|
||||||
multiDexEnabled =true
|
multiDexEnabled =true
|
||||||
|
|
||||||
// manifestPlaceholders can be specified here if needed
|
// manifestPlaceholders can be specified here if needed
|
||||||
|
|||||||
@@ -41,11 +41,11 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>67</string>
|
<string>69</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>4.3.67</string>
|
<string>4.3.69</string>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string></string>
|
<string></string>
|
||||||
<key>FirebaseAppDelegateProxyEnabled</key>
|
<key>FirebaseAppDelegateProxyEnabled</key>
|
||||||
|
|||||||
@@ -1,92 +1,12 @@
|
|||||||
// import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
|
||||||
// import 'package:get/get.dart';
|
|
||||||
// import 'package:timezone/data/latest.dart' as tz;
|
|
||||||
// import 'package:timezone/timezone.dart' as tz;
|
|
||||||
|
|
||||||
// class NotificationController extends GetxController {
|
|
||||||
// final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
|
|
||||||
// FlutterLocalNotificationsPlugin();
|
|
||||||
|
|
||||||
// // Initializes the local notifications plugin
|
|
||||||
// Future<void> initNotifications() async {
|
|
||||||
// const AndroidInitializationSettings android =
|
|
||||||
// AndroidInitializationSettings('@mipmap/launcher_icon');
|
|
||||||
// const InitializationSettings initializationSettings =
|
|
||||||
// InitializationSettings(android: android);
|
|
||||||
// await _flutterLocalNotificationsPlugin.initialize(initializationSettings);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Displays a notification with the given title and message
|
|
||||||
// void showNotification(String title, String message, String tone) async {
|
|
||||||
// AndroidNotificationDetails android = AndroidNotificationDetails(
|
|
||||||
// 'high_importance_channel',
|
|
||||||
// 'High Importance Notifications',
|
|
||||||
// importance: Importance.max,
|
|
||||||
// priority: Priority.high,
|
|
||||||
// showWhen: false,
|
|
||||||
// sound: RawResourceAndroidNotificationSound(tone),
|
|
||||||
// );
|
|
||||||
// DarwinNotificationDetails ios = const DarwinNotificationDetails(
|
|
||||||
// sound: 'default',
|
|
||||||
// presentAlert: true,
|
|
||||||
// presentBadge: true,
|
|
||||||
// presentSound: true,
|
|
||||||
// );
|
|
||||||
// NotificationDetails details =
|
|
||||||
// NotificationDetails(android: android, iOS: ios);
|
|
||||||
// await _flutterLocalNotificationsPlugin.show(0, title, message, details);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Schedules a notification after 1 minute
|
|
||||||
// void scheduleNotificationAfter1Minute(
|
|
||||||
// String title, String message, String tone) async {
|
|
||||||
// AndroidNotificationDetails android = AndroidNotificationDetails(
|
|
||||||
// 'high_importance_channel', 'High Importance Notifications',
|
|
||||||
// importance: Importance.max,
|
|
||||||
// priority: Priority.high,
|
|
||||||
// showWhen: false,
|
|
||||||
// sound: RawResourceAndroidNotificationSound(tone));
|
|
||||||
|
|
||||||
// DarwinNotificationDetails ios = const DarwinNotificationDetails(
|
|
||||||
// sound: 'default',
|
|
||||||
// presentAlert: true,
|
|
||||||
// presentBadge: true,
|
|
||||||
// presentSound: true,
|
|
||||||
// );
|
|
||||||
|
|
||||||
// NotificationDetails details =
|
|
||||||
// NotificationDetails(android: android, iOS: ios);
|
|
||||||
|
|
||||||
// // Schedule the notification to be shown after 1 minute
|
|
||||||
// final now = tz.TZDateTime.now(tz.local);
|
|
||||||
// final scheduledTime = now.add(const Duration(minutes: 1));
|
|
||||||
|
|
||||||
// await _flutterLocalNotificationsPlugin.zonedSchedule(
|
|
||||||
// 0,
|
|
||||||
// title,
|
|
||||||
// message,
|
|
||||||
// scheduledTime,
|
|
||||||
// details,
|
|
||||||
// androidAllowWhileIdle: true,
|
|
||||||
// uiLocalNotificationDateInterpretation:
|
|
||||||
// UILocalNotificationDateInterpretation.absoluteTime,
|
|
||||||
// matchDateTimeComponents: DateTimeComponents.time,
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:SEFER/constant/box_name.dart';
|
|
||||||
import 'package:SEFER/main.dart';
|
|
||||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
import 'package:timezone/data/latest.dart' as tz;
|
import 'package:timezone/data/latest.dart' as tz;
|
||||||
import 'package:timezone/timezone.dart' as tz;
|
import 'package:timezone/timezone.dart' as tz;
|
||||||
|
|
||||||
import '../../print.dart';
|
|
||||||
|
|
||||||
class NotificationController extends GetxController {
|
class NotificationController extends GetxController {
|
||||||
final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
|
final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
|
||||||
FlutterLocalNotificationsPlugin();
|
FlutterLocalNotificationsPlugin();
|
||||||
@@ -139,8 +59,11 @@ class NotificationController extends GetxController {
|
|||||||
await _flutterLocalNotificationsPlugin.show(0, title, message, details);
|
await _flutterLocalNotificationsPlugin.show(0, title, message, details);
|
||||||
print('Notification shown: $title - $message');
|
print('Notification shown: $title - $message');
|
||||||
}
|
}
|
||||||
|
// /Users/hamzaaleghwairyeen/development/App/ride 2/lib/controller/firebase/local_notification.dart
|
||||||
|
|
||||||
void scheduleDailyNotifications(
|
// Assume _flutterLocalNotificationsPlugin is initialized somewhere in your code
|
||||||
|
|
||||||
|
void scheduleNotificationsForSevenDays(
|
||||||
String title, String message, String tone) async {
|
String title, String message, String tone) async {
|
||||||
final AndroidNotificationDetails android = AndroidNotificationDetails(
|
final AndroidNotificationDetails android = AndroidNotificationDetails(
|
||||||
'high_importance_channel',
|
'high_importance_channel',
|
||||||
@@ -172,53 +95,68 @@ class NotificationController extends GetxController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Schedule notifications for 10:00 AM and 3:00 PM daily
|
// Schedule notifications for the next 7 days
|
||||||
await _scheduleNotificationForTime(8, 0, title, message, details);
|
for (int day = 0; day < 7; day++) {
|
||||||
await _scheduleNotificationForTime(15, 0, title, message, details);
|
// Schedule for 8:00 AM
|
||||||
await _scheduleNotificationForTime(20, 0, title, message, details);
|
await _scheduleNotificationForTime(
|
||||||
// await _scheduleNotificationForTime(0, 22, title, message, details);
|
day, 8, 0, title, message, details, day * 1000 + 1); // Unique ID
|
||||||
|
|
||||||
print('Daily notifications scheduled successfully');
|
// Schedule for 3:00 PM
|
||||||
|
await _scheduleNotificationForTime(
|
||||||
|
day, 15, 0, title, message, details, day * 1000 + 2); // Unique ID
|
||||||
|
|
||||||
|
// Schedule for 8:00 PM
|
||||||
|
await _scheduleNotificationForTime(
|
||||||
|
day, 20, 0, title, message, details, day * 1000 + 3); // Unique ID
|
||||||
|
}
|
||||||
|
|
||||||
|
print('Notifications scheduled successfully for the next 7 days');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to get the next instance of a specific hour and minute
|
Future<void> _scheduleNotificationForTime(
|
||||||
Future<void> _scheduleNotificationForTime(int hour, int minute, String title,
|
int dayOffset,
|
||||||
String message, NotificationDetails details) async {
|
int hour,
|
||||||
|
int minute,
|
||||||
|
String title,
|
||||||
|
String message,
|
||||||
|
NotificationDetails details,
|
||||||
|
int notificationId,
|
||||||
|
) async {
|
||||||
// Initialize and set Cairo timezone
|
// Initialize and set Cairo timezone
|
||||||
tz.initializeTimeZones();
|
tz.initializeTimeZones();
|
||||||
var cairoLocation;
|
var cairoLocation = tz.getLocation('Africa/Cairo');
|
||||||
// if (box.read(BoxName.countryCode).toString() == 'Egypt') {
|
|
||||||
cairoLocation = tz.getLocation('Africa/Cairo');
|
|
||||||
// } else {
|
|
||||||
// cairoLocation = tz.getLocation('UTC');
|
|
||||||
// } // todo get for location country
|
|
||||||
// Set Cairo timezone
|
|
||||||
Log.print('cairoLocation: ${cairoLocation}');
|
|
||||||
final now = tz.TZDateTime.now(
|
|
||||||
cairoLocation); // Use Cairo timezone for the current time
|
|
||||||
|
|
||||||
|
final now = tz.TZDateTime.now(cairoLocation);
|
||||||
tz.TZDateTime scheduledDate = tz.TZDateTime(
|
tz.TZDateTime scheduledDate = tz.TZDateTime(
|
||||||
cairoLocation, now.year, now.month, now.day, hour, minute);
|
cairoLocation,
|
||||||
|
now.year,
|
||||||
|
now.month,
|
||||||
|
now.day + dayOffset, // Add offset to schedule for the next days
|
||||||
|
hour,
|
||||||
|
minute,
|
||||||
|
);
|
||||||
|
|
||||||
// If scheduled time is already past today, schedule it for the next day
|
// If the scheduled time is in the past, move it to the next day
|
||||||
if (scheduledDate.isBefore(now)) {
|
if (scheduledDate.isBefore(now)) {
|
||||||
scheduledDate = scheduledDate.add(const Duration(days: 1));
|
scheduledDate = scheduledDate.add(Duration(days: 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
print('Current time (Cairo): $now');
|
print('Current time (Cairo): $now');
|
||||||
print('Scheduling notification for: $scheduledDate');
|
print('Scheduling notification for: $scheduledDate');
|
||||||
|
|
||||||
await _flutterLocalNotificationsPlugin.zonedSchedule(
|
await _flutterLocalNotificationsPlugin.zonedSchedule(
|
||||||
0, // Use unique IDs if you want to manage each notification separately
|
notificationId, // Unique ID for each notification
|
||||||
title,
|
title,
|
||||||
message,
|
message,
|
||||||
scheduledDate,
|
scheduledDate,
|
||||||
details,
|
details,
|
||||||
androidAllowWhileIdle: true,
|
androidScheduleMode: AndroidScheduleMode.exact,
|
||||||
uiLocalNotificationDateInterpretation:
|
uiLocalNotificationDateInterpretation:
|
||||||
UILocalNotificationDateInterpretation.absoluteTime,
|
UILocalNotificationDateInterpretation.absoluteTime,
|
||||||
matchDateTimeComponents: DateTimeComponents.time,
|
matchDateTimeComponents:
|
||||||
|
null, // Don't repeat automatically; we handle 7 days manually
|
||||||
);
|
);
|
||||||
print('Notification scheduled successfully for Cairo timezone');
|
|
||||||
|
print('Notification scheduled successfully for: $scheduledDate');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,13 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
|
||||||
import 'dart:ui';
|
|
||||||
import 'package:SEFER/constant/box_name.dart';
|
import 'package:SEFER/constant/box_name.dart';
|
||||||
import 'package:SEFER/constant/links.dart';
|
import 'package:SEFER/constant/links.dart';
|
||||||
import 'package:SEFER/main.dart';
|
import 'package:SEFER/main.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:SEFER/env/env.dart';
|
import 'package:SEFER/env/env.dart';
|
||||||
import 'package:http_parser/http_parser.dart';
|
|
||||||
import 'package:mime/mime.dart';
|
|
||||||
|
|
||||||
import '../../constant/api_key.dart';
|
import '../../constant/api_key.dart';
|
||||||
|
|
||||||
import '../../constant/colors.dart';
|
|
||||||
import '../../print.dart';
|
import '../../print.dart';
|
||||||
import '../../views/widgets/elevated_btn.dart';
|
import '../../views/widgets/elevated_btn.dart';
|
||||||
import 'add_error.dart';
|
import 'add_error.dart';
|
||||||
@@ -79,17 +74,20 @@ class CRUD {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future sendWhatsAppAuth(String to, String token) async {
|
Future sendWhatsAppAuth(String to, String token) async {
|
||||||
|
var res = await CRUD()
|
||||||
|
.get(link: AppLink.getApiKey, payload: {'keyName': 'whatsapp_key'});
|
||||||
|
var accesstoken = jsonDecode(res)['message']['whatsapp_key'];
|
||||||
var headers = {
|
var headers = {
|
||||||
'Authorization': 'Bearer ${Env.whatsapp}',
|
'Authorization': 'Bearer $accesstoken',
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
};
|
};
|
||||||
var request = http.Request(
|
|
||||||
'POST',
|
var url = 'https://graph.facebook.com/v20.0/${Env.whatappID}/messages';
|
||||||
Uri.parse(
|
var request = http.Request('POST', Uri.parse(url));
|
||||||
'https://graph.facebook.com/v20.0/${Env.whatappID}/messages'));
|
|
||||||
request.body = json.encode({
|
var body = json.encode({
|
||||||
"messaging_product": "whatsapp",
|
"messaging_product": "whatsapp",
|
||||||
"to": to, //"962798583052",
|
"to": to,
|
||||||
"type": "template",
|
"type": "template",
|
||||||
"template": {
|
"template": {
|
||||||
"name": "sefer1",
|
"name": "sefer1",
|
||||||
@@ -107,22 +105,38 @@ class CRUD {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
request.body = body;
|
||||||
request.headers.addAll(headers);
|
request.headers.addAll(headers);
|
||||||
|
|
||||||
http.StreamedResponse response = await request.send();
|
try {
|
||||||
|
print('Sending request to $url');
|
||||||
|
print('Request headers: $headers');
|
||||||
|
print('Request body: $body');
|
||||||
|
|
||||||
if (response.statusCode == 200) {
|
http.StreamedResponse response = await request.send();
|
||||||
print(await response.stream.bytesToString());
|
|
||||||
Get.defaultDialog(
|
if (response.statusCode == 200) {
|
||||||
|
String responseBody = await response.stream.bytesToString();
|
||||||
|
print('Response: $responseBody');
|
||||||
|
|
||||||
|
Get.defaultDialog(
|
||||||
title: 'You will receive a code in WhatsApp Messenger'.tr,
|
title: 'You will receive a code in WhatsApp Messenger'.tr,
|
||||||
middleText: 'wait 1 minute to recive message'.tr,
|
middleText: 'wait 1 minute to recive message'.tr,
|
||||||
confirm: MyElevatedButton(
|
confirm: MyElevatedButton(
|
||||||
title: 'OK'.tr,
|
title: 'OK'.tr,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Get.back();
|
Get.back();
|
||||||
}));
|
},
|
||||||
} else {
|
),
|
||||||
print(response.reasonPhrase);
|
);
|
||||||
|
} else {
|
||||||
|
String errorBody = await response.stream.bytesToString();
|
||||||
|
print('Error ${response.statusCode}: ${response.reasonPhrase}');
|
||||||
|
print('Error body: $errorBody');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print('Exception occurred: $e');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:math' show Random, cos, pi, pow, sin, sqrt;
|
import 'dart:math' show Random, cos, max, min, pi, pow, sin, sqrt;
|
||||||
import 'dart:math' as math;
|
import 'dart:math' as math;
|
||||||
|
import 'dart:ui';
|
||||||
import 'package:SEFER/constant/univeries_polygon.dart';
|
import 'package:SEFER/constant/univeries_polygon.dart';
|
||||||
|
import 'package:SEFER/controller/firebase/local_notification.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter_confetti/flutter_confetti.dart';
|
import 'package:flutter_confetti/flutter_confetti.dart';
|
||||||
import 'package:vector_math/vector_math.dart' show radians, degrees;
|
import 'package:vector_math/vector_math.dart' show radians, degrees;
|
||||||
|
|
||||||
@@ -1364,7 +1367,7 @@ class MapPassengerController extends GetxController {
|
|||||||
|
|
||||||
Set<String> notifiedDrivers = {};
|
Set<String> notifiedDrivers = {};
|
||||||
|
|
||||||
confirmRideForAllDriverAvailable() async {
|
confirmRideForAllDriverAvailable11() async {
|
||||||
// Fetch car locations
|
// Fetch car locations
|
||||||
await getCarsLocationByPassengerAndReloadMarker(
|
await getCarsLocationByPassengerAndReloadMarker(
|
||||||
box.read(BoxName.carType), 3000);
|
box.read(BoxName.carType), 3000);
|
||||||
@@ -1419,7 +1422,7 @@ class MapPassengerController extends GetxController {
|
|||||||
// Timer for 5 iterations, runs every 2 seconds
|
// Timer for 5 iterations, runs every 2 seconds
|
||||||
int iteration = 0;
|
int iteration = 0;
|
||||||
Timer.periodic(const Duration(seconds: 2), (timer) async {
|
Timer.periodic(const Duration(seconds: 2), (timer) async {
|
||||||
if (iteration >= 5) {
|
if (iteration >= 10) {
|
||||||
timer.cancel();
|
timer.cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1539,94 +1542,117 @@ class MapPassengerController extends GetxController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmRideForAllDriverAvailable1() async {
|
Future<void> confirmRideForAllDriverAvailable() async {
|
||||||
int attempts = 0;
|
// Try to fetch car locations up to 4 times with a 2-second delay
|
||||||
const int maxAttempts = 4;
|
bool driversFound = false;
|
||||||
const Duration delayDuration = Duration(seconds: 2);
|
for (int attempt = 0; attempt < 4; attempt++) {
|
||||||
|
await getCarsLocationByPassengerAndReloadMarker(
|
||||||
|
box.read(BoxName.carType), 3000);
|
||||||
|
|
||||||
// Initial data fetch
|
// Check if dataCarsLocationByPassenger is valid and contains drivers
|
||||||
await getCarsLocationByPassengerAndReloadMarker(
|
if (dataCarsLocationByPassenger != 'failure' &&
|
||||||
box.read(BoxName.carType), 3000);
|
dataCarsLocationByPassenger != null &&
|
||||||
|
dataCarsLocationByPassenger.containsKey('data') &&
|
||||||
if (dataCarsLocationByPassenger != null &&
|
dataCarsLocationByPassenger['data'] != null) {
|
||||||
dataCarsLocationByPassenger != 'failure') {
|
driversFound = true;
|
||||||
PaymentController paymentController = Get.find<PaymentController>();
|
break; // Exit loop if drivers are found
|
||||||
rideConfirm = true;
|
|
||||||
shouldFetch = true;
|
|
||||||
isBottomSheetShown = false;
|
|
||||||
timeToPassengerFromDriverAfterApplied = 60;
|
|
||||||
|
|
||||||
// Create a set to keep track of notified driver IDs
|
|
||||||
Set<String> notifiedDriverIds = {};
|
|
||||||
|
|
||||||
// Send the initial ride request once
|
|
||||||
rideId = await CRUD().post(
|
|
||||||
link: "${AppLink.seferCairoServer}/ride/rides/add.php",
|
|
||||||
payload: {
|
|
||||||
"start_location":
|
|
||||||
'${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
|
|
||||||
"end_location":
|
|
||||||
'${data[0]["end_location"]['lat']},${data[0]["end_location"]['lng']}',
|
|
||||||
"date": DateTime.now().toString(),
|
|
||||||
"time": DateTime.now().toString(),
|
|
||||||
"endtime": durationToAdd.toString(),
|
|
||||||
"price": totalPassenger.toStringAsFixed(2),
|
|
||||||
"passenger_id": box.read(BoxName.passengerID).toString(),
|
|
||||||
"driver_id": dataCarsLocationByPassenger['data'][carsOrder]
|
|
||||||
['driver_id']
|
|
||||||
.toString(),
|
|
||||||
"status": "waiting",
|
|
||||||
'carType': box.read(BoxName.carType),
|
|
||||||
"price_for_driver": totalPassenger.toString(),
|
|
||||||
"price_for_passenger": totalME.toString(),
|
|
||||||
"distance": distance.toString(),
|
|
||||||
"paymentMethod": paymentController.isWalletChecked.toString(),
|
|
||||||
}).then((value) => jsonDecode(value)['message']);
|
|
||||||
|
|
||||||
if (AppLink.endPoint != AppLink.seferCairoServer) {
|
|
||||||
CRUD().post(link: '${AppLink.endPoint}/ride/rides/add.php', payload: {
|
|
||||||
"start_location": //'${data[0]['start_address']}',
|
|
||||||
'${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
|
|
||||||
"end_location": //'${data[0]['end_address']}',
|
|
||||||
'${data[0]["end_location"]['lat']},${data[0]["end_location"]['lng']}',
|
|
||||||
"date": DateTime.now().toString(),
|
|
||||||
"time": DateTime.now().toString(),
|
|
||||||
"endtime": durationToAdd.toString(),
|
|
||||||
"price": totalPassenger.toStringAsFixed(2),
|
|
||||||
"passenger_id": box.read(BoxName.passengerID).toString(),
|
|
||||||
"driver_id": dataCarsLocationByPassenger['data'][carsOrder]
|
|
||||||
['driver_id']
|
|
||||||
.toString(),
|
|
||||||
"status": "waiting",
|
|
||||||
'carType': box.read(BoxName.carType),
|
|
||||||
"price_for_driver": totalPassenger.toString(),
|
|
||||||
"price_for_passenger": totalME.toString(),
|
|
||||||
"distance": distance.toString(),
|
|
||||||
"paymentMethod": paymentController.isWalletChecked.toString(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// Add the initially available drivers to the notified set
|
|
||||||
for (var driver in dataCarsLocationByPassenger['data']) {
|
|
||||||
notifiedDriverIds.add(driver['driver_id'].toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Periodically check for new drivers
|
// Wait 2 seconds before next attempt
|
||||||
Timer.periodic(delayDuration, (Timer timer) async {
|
await Future.delayed(const Duration(seconds: 2));
|
||||||
attempts++;
|
}
|
||||||
|
|
||||||
|
// If no drivers were found after 4 attempts, show a dialog
|
||||||
|
if (!driversFound) {
|
||||||
|
Get.dialog(
|
||||||
|
BackdropFilter(
|
||||||
|
filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5),
|
||||||
|
child: CupertinoAlertDialog(
|
||||||
|
title: Text(
|
||||||
|
"No Car or Driver Found in your area.".tr,
|
||||||
|
style: AppStyle.title.copyWith(
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
content: Text(
|
||||||
|
"No Car or Driver Found in your area.".tr,
|
||||||
|
style: AppStyle.title.copyWith(fontSize: 16),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
CupertinoDialogAction(
|
||||||
|
onPressed: () {
|
||||||
|
Get.back();
|
||||||
|
Get.offAll(() => const MapPagePassenger());
|
||||||
|
},
|
||||||
|
child: Text('OK'.tr,
|
||||||
|
style: const TextStyle(color: AppColor.greenColor)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
barrierDismissible: false,
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Proceed with the rest of the function if drivers are found
|
||||||
|
PaymentController paymentController = Get.find<PaymentController>();
|
||||||
|
rideConfirm = true;
|
||||||
|
shouldFetch = true;
|
||||||
|
isBottomSheetShown = false;
|
||||||
|
timeToPassengerFromDriverAfterApplied = 60;
|
||||||
|
|
||||||
|
// Add ride to database
|
||||||
|
await CRUD()
|
||||||
|
.post(link: "${AppLink.seferCairoServer}/ride/rides/add.php", payload: {
|
||||||
|
"start_location":
|
||||||
|
'${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
|
||||||
|
"end_location":
|
||||||
|
'${data[0]["end_location"]['lat']},${data[0]["end_location"]['lng']}',
|
||||||
|
"date": DateTime.now().toString(),
|
||||||
|
"time": DateTime.now().toString(),
|
||||||
|
"endtime": durationToAdd.toString(),
|
||||||
|
"price": totalPassenger.toStringAsFixed(2),
|
||||||
|
"passenger_id": box.read(BoxName.passengerID).toString(),
|
||||||
|
"driver_id": dataCarsLocationByPassenger['data'][carsOrder]['driver_id']
|
||||||
|
.toString(),
|
||||||
|
"status": "waiting",
|
||||||
|
'carType': box.read(BoxName.carType),
|
||||||
|
"price_for_driver": totalPassenger.toString(),
|
||||||
|
"price_for_passenger": totalME.toString(),
|
||||||
|
"distance": distance.toString(),
|
||||||
|
"paymentMethod": paymentController.isWalletChecked.toString(),
|
||||||
|
}).then((value) {
|
||||||
|
if (value is String) {
|
||||||
|
final parsedValue = jsonDecode(value);
|
||||||
|
rideId = parsedValue['message'];
|
||||||
|
} else if (value is Map) {
|
||||||
|
rideId = value['message'];
|
||||||
|
} else {
|
||||||
|
Log.print('Unexpected response type: ${value.runtimeType}');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timer to notify drivers every 2 seconds for 5 iterations
|
||||||
|
int iteration = 0;
|
||||||
|
Timer.periodic(const Duration(seconds: 2), (timer) async {
|
||||||
|
if (iteration >= 5) {
|
||||||
|
timer.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
iteration++;
|
||||||
|
|
||||||
|
// Reload driver locations and notify available drivers
|
||||||
await getCarsLocationByPassengerAndReloadMarker(
|
await getCarsLocationByPassengerAndReloadMarker(
|
||||||
box.read(BoxName.carType), 3000);
|
box.read(BoxName.carType), 3000);
|
||||||
|
if (dataCarsLocationByPassenger != null &&
|
||||||
if (dataCarsLocationByPassenger != 'failure') {
|
dataCarsLocationByPassenger.containsKey('data') &&
|
||||||
// Check for new drivers and notify them
|
dataCarsLocationByPassenger['data'] != null) {
|
||||||
for (var driver in dataCarsLocationByPassenger['data']) {
|
for (var driverData in dataCarsLocationByPassenger['data']) {
|
||||||
String driverId = driver['driver_id'].toString();
|
String driverId = driverData['driver_id'].toString();
|
||||||
|
if (!notifiedDrivers.contains(driverId)) {
|
||||||
// Only notify new drivers
|
notifiedDrivers.add(driverId);
|
||||||
if (!notifiedDriverIds.contains(driverId)) {
|
|
||||||
notifiedDriverIds.add(driverId);
|
|
||||||
|
|
||||||
// Prepare notification body
|
|
||||||
List<String> body = [
|
List<String> body = [
|
||||||
'${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
|
'${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
|
||||||
'${data[0]["end_location"]['lat']},${data[0]["end_location"]['lng']}',
|
'${data[0]["end_location"]['lat']},${data[0]["end_location"]['lng']}',
|
||||||
@@ -1642,10 +1668,11 @@ class MapPassengerController extends GetxController {
|
|||||||
durationByPassenger.toString(),
|
durationByPassenger.toString(),
|
||||||
distanceByPassenger.toString(),
|
distanceByPassenger.toString(),
|
||||||
paymentController.isWalletChecked.toString(),
|
paymentController.isWalletChecked.toString(),
|
||||||
driver['token'].toString(),
|
driverData['token'].toString(),
|
||||||
durationToPassenger.toString(),
|
durationToPassenger.toString(),
|
||||||
rideId,
|
rideId,
|
||||||
rideTimerBegin.toString(),
|
rideTimerBegin.toString(),
|
||||||
|
driverId,
|
||||||
durationToRide.toString(),
|
durationToRide.toString(),
|
||||||
Get.find<WayPointController>().wayPoints.length > 1
|
Get.find<WayPointController>().wayPoints.length > 1
|
||||||
? 'haveSteps'
|
? 'haveSteps'
|
||||||
@@ -1656,10 +1683,10 @@ class MapPassengerController extends GetxController {
|
|||||||
placesCoordinate[3],
|
placesCoordinate[3],
|
||||||
placesCoordinate[4],
|
placesCoordinate[4],
|
||||||
costForDriver.toStringAsFixed(2),
|
costForDriver.toStringAsFixed(2),
|
||||||
double.parse(box.read(BoxName.passengerWalletTotal)) < 0
|
(double.parse(box.read(BoxName.passengerWalletTotal)) < 0
|
||||||
? double.parse(box.read(BoxName.passengerWalletTotal))
|
? double.parse(box.read(BoxName.passengerWalletTotal))
|
||||||
.toStringAsFixed(2)
|
.toStringAsFixed(2)
|
||||||
: '0',
|
: '0'),
|
||||||
box.read(BoxName.email).toString(),
|
box.read(BoxName.email).toString(),
|
||||||
data[0]['start_address'],
|
data[0]['start_address'],
|
||||||
data[0]['end_address'],
|
data[0]['end_address'],
|
||||||
@@ -1667,37 +1694,43 @@ class MapPassengerController extends GetxController {
|
|||||||
kazan.toStringAsFixed(0),
|
kazan.toStringAsFixed(0),
|
||||||
passengerRate.toStringAsFixed(2),
|
passengerRate.toStringAsFixed(2),
|
||||||
];
|
];
|
||||||
|
|
||||||
// Send notification to the new driver
|
|
||||||
FirebaseMessagesController().sendNotificationToDriverMAP(
|
FirebaseMessagesController().sendNotificationToDriverMAP(
|
||||||
'OrderSpeed',
|
'OrderSpeed',
|
||||||
rideId.toString(),
|
rideId,
|
||||||
driver['token'].toString(),
|
driverData['token'].toString(),
|
||||||
body,
|
body,
|
||||||
'order.wav',
|
'order.wav',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
MyDialog().getDialog("No Car or Driver Found in your area.".tr,
|
|
||||||
"No Car or Driver Found in your area.".tr, () {
|
|
||||||
Get.back();
|
|
||||||
Get.offAll(const MapPagePassenger());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop after max attempts
|
|
||||||
if (attempts >= maxAttempts) {
|
|
||||||
timer.cancel();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
});
|
||||||
MyDialog().getDialog("No Car or Driver Found in your area.".tr,
|
|
||||||
"No Car or Driver Found in your area.".tr, () {
|
// If an additional endpoint is available, post data there as well
|
||||||
Get.back();
|
if (AppLink.endPoint != AppLink.seferCairoServer) {
|
||||||
Get.offAll(const MapPagePassenger());
|
CRUD().post(link: '${AppLink.endPoint}/ride/rides/add.php', payload: {
|
||||||
|
"start_location":
|
||||||
|
'${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
|
||||||
|
"end_location":
|
||||||
|
'${data[0]["end_location"]['lat']},${data[0]["end_location"]['lng']}',
|
||||||
|
"date": DateTime.now().toString(),
|
||||||
|
"time": DateTime.now().toString(),
|
||||||
|
"endtime": durationToAdd.toString(),
|
||||||
|
"price": totalPassenger.toStringAsFixed(2),
|
||||||
|
"passenger_id": box.read(BoxName.passengerID).toString(),
|
||||||
|
"driver_id": dataCarsLocationByPassenger['data'][carsOrder]['driver_id']
|
||||||
|
.toString(),
|
||||||
|
"status": "waiting",
|
||||||
|
'carType': box.read(BoxName.carType),
|
||||||
|
"price_for_driver": totalPassenger.toString(),
|
||||||
|
"price_for_passenger": totalME.toString(),
|
||||||
|
"distance": distance.toString(),
|
||||||
|
"paymentMethod": paymentController.isWalletChecked.toString(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
delayAndFetchRideStatusForAllDriverAvailable(rideId);
|
||||||
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
icreaseForSameRideAndDelay() {
|
icreaseForSameRideAndDelay() {
|
||||||
@@ -1781,7 +1814,7 @@ class MapPassengerController extends GetxController {
|
|||||||
confirmRideForAllDriverAvailable();
|
confirmRideForAllDriverAvailable();
|
||||||
// delayAndFetchRideStatusForAllDriverAvailable(rideId);
|
// delayAndFetchRideStatusForAllDriverAvailable(rideId);
|
||||||
} else if (rideStatusDelayed == 'Apply' || statusRide == 'Apply') {
|
} else if (rideStatusDelayed == 'Apply' || statusRide == 'Apply') {
|
||||||
Log.print('rideStatusDelayed == Apply: ${rideStatusDelayed}');
|
Log.print('rideStatusDelayed == Apply: $rideStatusDelayed');
|
||||||
// todo play sound
|
// todo play sound
|
||||||
Get.find<AudioRecorderController>()
|
Get.find<AudioRecorderController>()
|
||||||
.playSoundFromAssets('assets/start.wav');
|
.playSoundFromAssets('assets/start.wav');
|
||||||
@@ -1837,17 +1870,29 @@ class MapPassengerController extends GetxController {
|
|||||||
int attemptCounter = 0;
|
int attemptCounter = 0;
|
||||||
bool isApplied = false;
|
bool isApplied = false;
|
||||||
tick = 0;
|
tick = 0;
|
||||||
Log.print('tick delayAndFetchRideStatusForAllDriverAvailable: $tick');
|
bool shouldContinueSearching = true; // Flag to control searching
|
||||||
|
|
||||||
void fetchRideStatus() async {
|
void fetchRideStatus() async {
|
||||||
if (attemptCounter < maxAttempts && isApplied == false || tick < 15) {
|
if (attemptCounter < maxAttempts &&
|
||||||
|
!isApplied &&
|
||||||
|
shouldContinueSearching) {
|
||||||
attemptCounter++;
|
attemptCounter++;
|
||||||
tick++;
|
tick++;
|
||||||
var res = await getRideStatus(rideId);
|
var res = await getRideStatus(rideId);
|
||||||
String rideStatusDelayed = res.toString();
|
String rideStatusDelayed = res.toString();
|
||||||
|
|
||||||
if (rideStatusDelayed == 'Apply' || rideStatusDelayed == 'Applied') {
|
if (rideStatusDelayed == 'Cancel') {
|
||||||
|
shouldContinueSearching = false; // Stop searching
|
||||||
|
attemptCounter = maxAttempts + 1;
|
||||||
|
NotificationController().showNotification(
|
||||||
|
"Order Cancelled".tr, "you canceled order".tr, 'ding');
|
||||||
|
} else if (rideStatusDelayed == 'Apply' ||
|
||||||
|
rideStatusDelayed == 'Applied') {
|
||||||
await getUpdatedRideForDriverApply(rideId);
|
await getUpdatedRideForDriverApply(rideId);
|
||||||
|
NotificationController().showNotification(
|
||||||
|
'Order Accepted'.tr,
|
||||||
|
'$driverName ${'accepted your order at price'.tr} ${totalPassenger.toStringAsFixed(1)} ${'with type'.tr} ${box.read(BoxName.carType)}',
|
||||||
|
'ding');
|
||||||
isApplied = true;
|
isApplied = true;
|
||||||
shouldFetch = false;
|
shouldFetch = false;
|
||||||
statusRide = 'Apply';
|
statusRide = 'Apply';
|
||||||
@@ -1855,89 +1900,14 @@ class MapPassengerController extends GetxController {
|
|||||||
isSearchingWindow = false;
|
isSearchingWindow = false;
|
||||||
|
|
||||||
startTimer();
|
startTimer();
|
||||||
|
|
||||||
update();
|
update();
|
||||||
startTimerFromDriverToPassengerAfterApplied();
|
startTimerFromDriverToPassengerAfterApplied();
|
||||||
|
shouldContinueSearching = false; // Stop searching if applied
|
||||||
} else if (attemptCounter >= maxAttempts &&
|
} else if (attemptCounter >= maxAttempts &&
|
||||||
rideStatusDelayed != 'Cancel') {
|
rideStatusDelayed != 'Cancel') {
|
||||||
shouldFetch = false;
|
shouldContinueSearching = false; // Stop searching
|
||||||
// If the status is still not "Apply" after 15 attempts
|
// Show dialog to increase fee...
|
||||||
MyDialog().getDialog('upgrade price'.tr,
|
|
||||||
'You can upgrade price to may driver accept your order'.tr, () {
|
|
||||||
Get.back();
|
|
||||||
Get.defaultDialog(
|
|
||||||
barrierDismissible: false,
|
|
||||||
title: "Increase Your Trip Fee (Optional)".tr,
|
|
||||||
titleStyle: AppStyle.title,
|
|
||||||
content: Column(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
"We haven't found any drivers yet. Consider increasing your trip fee to make your offer more attractive to drivers."
|
|
||||||
.tr,
|
|
||||||
style: AppStyle.title,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
IconButton(
|
|
||||||
onPressed: () {
|
|
||||||
increasFeeFromPassenger.text =
|
|
||||||
(totalPassenger + 6).toStringAsFixed(1);
|
|
||||||
update();
|
|
||||||
},
|
|
||||||
icon: Column(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'6',
|
|
||||||
style: AppStyle.number,
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
decoration: const BoxDecoration(
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
color: AppColor.greenColor),
|
|
||||||
child: const Icon(
|
|
||||||
Icons.arrow_circle_up,
|
|
||||||
size: 30,
|
|
||||||
color: AppColor.secondaryColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
width: 100,
|
|
||||||
child: Form(
|
|
||||||
key: increaseFeeFormKey,
|
|
||||||
child: MyTextForm(
|
|
||||||
controller: increasFeeFromPassenger,
|
|
||||||
label: totalPassenger.toStringAsFixed(2),
|
|
||||||
hint: totalPassenger.toStringAsFixed(2),
|
|
||||||
type: TextInputType.number),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
actions: [
|
|
||||||
MyElevatedButton(
|
|
||||||
title: "No, thanks",
|
|
||||||
onPressed: () async {
|
|
||||||
await cancelRide();
|
|
||||||
Get.back();
|
|
||||||
}),
|
|
||||||
MyElevatedButton(
|
|
||||||
title: "Increase Fee".tr,
|
|
||||||
kolor: AppColor.greenColor,
|
|
||||||
onPressed: () {
|
|
||||||
increaseFeeByPassengerAndReOrder();
|
|
||||||
})
|
|
||||||
],
|
|
||||||
);
|
|
||||||
});
|
|
||||||
update();
|
update();
|
||||||
print('Stopped fetching ride status after 15 attempts.');
|
|
||||||
} else {
|
} else {
|
||||||
Timer(const Duration(seconds: 2), fetchRideStatus);
|
Timer(const Duration(seconds: 2), fetchRideStatus);
|
||||||
}
|
}
|
||||||
@@ -2026,7 +1996,7 @@ class MapPassengerController extends GetxController {
|
|||||||
FirebaseMessagesController().sendNotificationToDriverMAP(
|
FirebaseMessagesController().sendNotificationToDriverMAP(
|
||||||
'Order Applied'.tr,
|
'Order Applied'.tr,
|
||||||
'$driverName Apply order\nTake attention in other order'.tr,
|
'$driverName Apply order\nTake attention in other order'.tr,
|
||||||
driverToken,
|
driverToken.toString(),
|
||||||
[],
|
[],
|
||||||
'start.wav',
|
'start.wav',
|
||||||
);
|
);
|
||||||
@@ -2912,7 +2882,7 @@ class MapPassengerController extends GetxController {
|
|||||||
FirebaseMessagesController().sendNotificationToDriverMAP(
|
FirebaseMessagesController().sendNotificationToDriverMAP(
|
||||||
'Cancel Trip'.tr,
|
'Cancel Trip'.tr,
|
||||||
'Trip Cancelled'.tr,
|
'Trip Cancelled'.tr,
|
||||||
driverToken,
|
driverToken.toString(),
|
||||||
[],
|
[],
|
||||||
'cancel.wav',
|
'cancel.wav',
|
||||||
);
|
);
|
||||||
@@ -3313,23 +3283,56 @@ class MapPassengerController extends GetxController {
|
|||||||
// Log.print('BoxName.serverChosen: ${box.read(BoxName.serverChosen)}');
|
// Log.print('BoxName.serverChosen: ${box.read(BoxName.serverChosen)}');
|
||||||
|
|
||||||
newStartPointLocation = passengerLocation;
|
newStartPointLocation = passengerLocation;
|
||||||
Log.print('passengerLocation: ${passengerLocation}');
|
Log.print('passengerLocation: $passengerLocation');
|
||||||
speed = _locationData.speed!;
|
speed = _locationData.speed!;
|
||||||
// //print location details
|
// //print location details
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LatLngBounds calculateBounds(double lat, double lng, double radiusInMeters) {
|
||||||
|
// const double earthRadius = 6378137.0; // Earth's radius in meters
|
||||||
|
|
||||||
|
// double latDelta = radiusInMeters / earthRadius * (180 / pi);
|
||||||
|
// double lngDelta =
|
||||||
|
// radiusInMeters / (earthRadius * cos(pi * lat / 180)) * (180 / pi);
|
||||||
|
|
||||||
|
// return LatLngBounds(
|
||||||
|
// southwest: LatLng(lat - latDelta, lng - lngDelta),
|
||||||
|
// northeast: LatLng(lat + latDelta, lng + lngDelta),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
LatLngBounds calculateBounds(double lat, double lng, double radiusInMeters) {
|
LatLngBounds calculateBounds(double lat, double lng, double radiusInMeters) {
|
||||||
const double earthRadius = 6378137.0; // Earth's radius in meters
|
const double earthRadius = 6378137.0; // Earth's radius in meters
|
||||||
|
|
||||||
double latDelta = radiusInMeters / earthRadius * (180 / pi);
|
double latDelta = (radiusInMeters / earthRadius) * (180 / pi);
|
||||||
double lngDelta =
|
double lngDelta =
|
||||||
radiusInMeters / (earthRadius * cos(pi * lat / 180)) * (180 / pi);
|
(radiusInMeters / (earthRadius * cos(pi * lat / 180))) * (180 / pi);
|
||||||
|
|
||||||
|
double minLat = lat - latDelta;
|
||||||
|
double maxLat = lat + latDelta;
|
||||||
|
|
||||||
|
double minLng = lng - lngDelta;
|
||||||
|
double maxLng = lng + lngDelta;
|
||||||
|
|
||||||
|
// Ensure the latitude is between -90 and 90
|
||||||
|
minLat = max(-90.0, minLat);
|
||||||
|
maxLat = min(90.0, maxLat);
|
||||||
|
|
||||||
|
// Ensure the longitude is between -180 and 180
|
||||||
|
minLng = (minLng + 180) % 360 - 180;
|
||||||
|
maxLng = (maxLng + 180) % 360 - 180;
|
||||||
|
|
||||||
|
// Ensure the bounds are in the correct order
|
||||||
|
if (minLng > maxLng) {
|
||||||
|
double temp = minLng;
|
||||||
|
minLng = maxLng;
|
||||||
|
maxLng = temp;
|
||||||
|
}
|
||||||
|
|
||||||
return LatLngBounds(
|
return LatLngBounds(
|
||||||
southwest: LatLng(lat - latDelta, lng - lngDelta),
|
southwest: LatLng(minLat, minLng),
|
||||||
northeast: LatLng(lat + latDelta, lng + lngDelta),
|
northeast: LatLng(maxLat, maxLng),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3470,7 +3473,7 @@ class MapPassengerController extends GetxController {
|
|||||||
i < dataCarsLocationByPassenger['message'].length;
|
i < dataCarsLocationByPassenger['message'].length;
|
||||||
i++) {
|
i++) {
|
||||||
var carLocation = dataCarsLocationByPassenger['message'][i];
|
var carLocation = dataCarsLocationByPassenger['message'][i];
|
||||||
Log.print('carLocation: ${carLocation}');
|
Log.print('carLocation: $carLocation');
|
||||||
|
|
||||||
// Calculate distance between passenger's location and current driver's location
|
// Calculate distance between passenger's location and current driver's location
|
||||||
final distance = Geolocator.distanceBetween(
|
final distance = Geolocator.distanceBetween(
|
||||||
@@ -3482,8 +3485,8 @@ class MapPassengerController extends GetxController {
|
|||||||
|
|
||||||
// Calculate duration assuming an average speed of 25 km/h (adjust as needed)
|
// Calculate duration assuming an average speed of 25 km/h (adjust as needed)
|
||||||
int durationToPassenger = (distance * 25 * (1000 / 3600)).round();
|
int durationToPassenger = (distance * 25 * (1000 / 3600)).round();
|
||||||
Log.print('distance: ${distance}');
|
Log.print('distance: $distance');
|
||||||
Log.print('durationToPassenger: ${durationToPassenger}');
|
Log.print('durationToPassenger: $durationToPassenger');
|
||||||
|
|
||||||
// Update the UI with the distance and duration for each car
|
// Update the UI with the distance and duration for each car
|
||||||
update();
|
update();
|
||||||
@@ -3499,7 +3502,7 @@ class MapPassengerController extends GetxController {
|
|||||||
latitude: double.parse(carLocation['latitude']),
|
latitude: double.parse(carLocation['latitude']),
|
||||||
longitude: double.parse(carLocation['longitude']),
|
longitude: double.parse(carLocation['longitude']),
|
||||||
);
|
);
|
||||||
Log.print('nearestCar: ${nearestCar}');
|
Log.print('nearestCar: $nearestCar');
|
||||||
// Update the UI with the nearest driver
|
// Update the UI with the nearest driver
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
@@ -4283,7 +4286,7 @@ class MapPassengerController extends GetxController {
|
|||||||
totalCostPassenger = totalDriver1 + (totalDriver1 * kazan / 100);
|
totalCostPassenger = totalDriver1 + (totalDriver1 * kazan / 100);
|
||||||
totalPassenger = costSpeed + (costSpeed * kazan / 100);
|
totalPassenger = costSpeed + (costSpeed * kazan / 100);
|
||||||
if (isInUniversity) {
|
if (isInUniversity) {
|
||||||
Log.print('isInUniversity: ${isInUniversity}');
|
Log.print('isInUniversity: $isInUniversity');
|
||||||
totalPassengerComfort =
|
totalPassengerComfort =
|
||||||
20 + (costComfort + (costComfort * kazan / 100)).ceilToDouble();
|
20 + (costComfort + (costComfort * kazan / 100)).ceilToDouble();
|
||||||
totalPassengerLady =
|
totalPassengerLady =
|
||||||
@@ -4325,7 +4328,7 @@ class MapPassengerController extends GetxController {
|
|||||||
totalME = totalCostPassenger - tax;
|
totalME = totalCostPassenger - tax;
|
||||||
costForDriver = fuelPrice * (20 / 210) * distance;
|
costForDriver = fuelPrice * (20 / 210) * distance;
|
||||||
} else {
|
} else {
|
||||||
Log.print('isInUniversity: ${isInUniversity}');
|
Log.print('isInUniversity: $isInUniversity');
|
||||||
totalPassengerComfort =
|
totalPassengerComfort =
|
||||||
(costComfort + (costComfort * kazan / 100)).ceilToDouble();
|
(costComfort + (costComfort * kazan / 100)).ceilToDouble();
|
||||||
totalPassengerLady =
|
totalPassengerLady =
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import 'package:SEFER/constant/box_name.dart';
|
|||||||
import 'package:SEFER/constant/colors.dart';
|
import 'package:SEFER/constant/colors.dart';
|
||||||
import 'package:SEFER/constant/links.dart';
|
import 'package:SEFER/constant/links.dart';
|
||||||
import 'package:SEFER/controller/functions/crud.dart';
|
import 'package:SEFER/controller/functions/crud.dart';
|
||||||
import 'package:SEFER/controller/home/payment/captain_wallet_controller.dart';
|
|
||||||
import 'package:SEFER/controller/payment/payment_controller.dart';
|
import 'package:SEFER/controller/payment/payment_controller.dart';
|
||||||
|
import 'package:SEFER/views/widgets/mysnakbar.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_contacts/contact.dart';
|
import 'package:flutter_contacts/contact.dart';
|
||||||
import 'package:flutter_contacts/flutter_contacts.dart';
|
import 'package:flutter_contacts/flutter_contacts.dart';
|
||||||
@@ -13,6 +13,7 @@ import 'package:get/get.dart';
|
|||||||
import 'package:share/share.dart';
|
import 'package:share/share.dart';
|
||||||
|
|
||||||
import '../../../main.dart';
|
import '../../../main.dart';
|
||||||
|
import '../../../print.dart';
|
||||||
import '../../../views/widgets/my_dialog.dart';
|
import '../../../views/widgets/my_dialog.dart';
|
||||||
import '../../functions/launch.dart';
|
import '../../functions/launch.dart';
|
||||||
import '../../notification/notification_captain_controller.dart';
|
import '../../notification/notification_captain_controller.dart';
|
||||||
@@ -117,23 +118,49 @@ Download the SEFER app now and enjoy your ride!
|
|||||||
|
|
||||||
Future<void> pickContacts() async {
|
Future<void> pickContacts() async {
|
||||||
try {
|
try {
|
||||||
|
// Request contacts permission
|
||||||
if (await FlutterContacts.requestPermission(readonly: true)) {
|
if (await FlutterContacts.requestPermission(readonly: true)) {
|
||||||
final List<Contact> fetchedContacts =
|
// Fetch all contacts with full properties
|
||||||
await FlutterContacts.getContacts(withProperties: true);
|
final List<Contact> allContacts = await FlutterContacts.getContacts(
|
||||||
contacts = fetchedContacts;
|
withProperties: true,
|
||||||
|
withThumbnail: false,
|
||||||
|
withPhoto: true,
|
||||||
|
);
|
||||||
|
|
||||||
// Convert contacts to a list of maps
|
// Check if contacts are available
|
||||||
contactMaps.value = fetchedContacts.map((contact) {
|
if (allContacts.isNotEmpty) {
|
||||||
return {
|
// Store the contacts
|
||||||
'name': contact.displayName,
|
contacts = allContacts;
|
||||||
'phones':
|
Log.print('contacts: $contacts');
|
||||||
contact.phones.map((phone) => phone.normalizedNumber).toList(),
|
|
||||||
'emails': contact.emails.map((email) => email.address).toList(),
|
|
||||||
};
|
|
||||||
}).toList();
|
|
||||||
update();
|
|
||||||
|
|
||||||
if (contacts.isEmpty) {
|
// Convert contacts to a list of maps
|
||||||
|
contactMaps.value = await Future.wait(contacts.map((contact) async {
|
||||||
|
Log.print('Contact name: ${contact.displayName}');
|
||||||
|
|
||||||
|
// Fetch phone numbers separately
|
||||||
|
final phones = await contact.phones;
|
||||||
|
Log.print('Contact phones: $phones');
|
||||||
|
|
||||||
|
// Fetch email addresses separately
|
||||||
|
final emails = await contact.emails;
|
||||||
|
Log.print('Contact emails: $emails');
|
||||||
|
|
||||||
|
// Handle empty or null values
|
||||||
|
return {
|
||||||
|
'name': contact.displayName ?? '',
|
||||||
|
'phones': phones
|
||||||
|
.where((phone) => phone.normalizedNumber != null)
|
||||||
|
.map((phone) => phone.normalizedNumber ?? 'No number')
|
||||||
|
.toList(),
|
||||||
|
'emails': emails
|
||||||
|
.where((email) => email.address != null)
|
||||||
|
.map((email) => email.address ?? 'No email')
|
||||||
|
.toList(),
|
||||||
|
};
|
||||||
|
}).toList());
|
||||||
|
|
||||||
|
update();
|
||||||
|
} else {
|
||||||
Get.snackbar('No contacts available'.tr,
|
Get.snackbar('No contacts available'.tr,
|
||||||
'Please add contacts to your phone.'.tr);
|
'Please add contacts to your phone.'.tr);
|
||||||
}
|
}
|
||||||
@@ -225,8 +252,10 @@ Download the SEFER app now and enjoy your ride!
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sendInviteToPassenger() async {
|
void sendInviteToPassenger() async {
|
||||||
if (invitePhoneController.text.isEmpty) {
|
if (invitePhoneController.text.isEmpty ||
|
||||||
Get.snackbar('Error', 'Please enter an phone address'.tr);
|
invitePhoneController.text.length < 11) {
|
||||||
|
mySnackeBarError('Please enter a correct phone'.tr);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,72 +20,58 @@ class LocaleController extends GetxController {
|
|||||||
case "ar":
|
case "ar":
|
||||||
locale = const Locale("ar");
|
locale = const Locale("ar");
|
||||||
appTheme = themeArabic;
|
appTheme = themeArabic;
|
||||||
box.write(BoxName.lang, 'ar');
|
|
||||||
break;
|
break;
|
||||||
case "en":
|
case "en":
|
||||||
locale = const Locale("en");
|
locale = const Locale("en");
|
||||||
appTheme = themeEnglish;
|
appTheme = themeEnglish;
|
||||||
box.write(BoxName.lang, 'en');
|
|
||||||
break;
|
break;
|
||||||
case "tr":
|
case "tr":
|
||||||
locale = const Locale("tr");
|
locale = const Locale("tr");
|
||||||
appTheme = themeEnglish;
|
appTheme = themeEnglish;
|
||||||
box.write(BoxName.lang, 'tr');
|
|
||||||
break;
|
break;
|
||||||
case "fr":
|
case "fr":
|
||||||
locale = const Locale("fr");
|
locale = const Locale("fr");
|
||||||
appTheme = themeEnglish;
|
appTheme = themeEnglish;
|
||||||
box.write(BoxName.lang, 'fr');
|
|
||||||
break;
|
break;
|
||||||
case "it":
|
case "it":
|
||||||
locale = const Locale("it");
|
locale = const Locale("it");
|
||||||
appTheme = themeEnglish;
|
appTheme = themeEnglish;
|
||||||
box.write(BoxName.lang, 'it');
|
|
||||||
break;
|
break;
|
||||||
case "de":
|
case "de":
|
||||||
locale = const Locale("de");
|
locale = const Locale("de");
|
||||||
appTheme = themeEnglish;
|
appTheme = themeEnglish;
|
||||||
box.write(BoxName.lang, 'de');
|
|
||||||
break;
|
break;
|
||||||
case "el":
|
case "el":
|
||||||
locale = const Locale("el");
|
locale = const Locale("el");
|
||||||
appTheme = themeEnglish;
|
appTheme = themeEnglish;
|
||||||
box.write(BoxName.lang, 'el');
|
|
||||||
break;
|
break;
|
||||||
case "es":
|
case "es":
|
||||||
locale = const Locale("es");
|
locale = const Locale("es");
|
||||||
appTheme = themeEnglish;
|
appTheme = themeEnglish;
|
||||||
box.write(BoxName.lang, 'es');
|
|
||||||
break;
|
break;
|
||||||
case "fa":
|
case "fa":
|
||||||
locale = const Locale("fa");
|
locale = const Locale("fa");
|
||||||
appTheme = themeEnglish;
|
appTheme = themeArabic;
|
||||||
box.write(BoxName.lang, 'fa');
|
|
||||||
break;
|
break;
|
||||||
case "zh":
|
case "zh":
|
||||||
locale = const Locale("zh");
|
locale = const Locale("zh");
|
||||||
appTheme = themeEnglish;
|
appTheme = themeEnglish;
|
||||||
box.write(BoxName.lang, 'zh');
|
|
||||||
break;
|
break;
|
||||||
case "ru":
|
case "ru":
|
||||||
locale = const Locale("ru");
|
locale = const Locale("ru");
|
||||||
appTheme = themeEnglish;
|
appTheme = themeEnglish;
|
||||||
box.write(BoxName.lang, 'ru');
|
|
||||||
break;
|
break;
|
||||||
case "hi":
|
case "hi":
|
||||||
locale = const Locale("hi");
|
locale = const Locale("hi");
|
||||||
appTheme = themeEnglish;
|
appTheme = themeEnglish;
|
||||||
box.write(BoxName.lang, 'hi');
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
locale = Locale(Get.deviceLocale!.languageCode);
|
locale = Locale(Get.deviceLocale!.languageCode);
|
||||||
box.write(BoxName.lang, Get.deviceLocale!.languageCode);
|
|
||||||
appTheme = themeEnglish;
|
appTheme = themeEnglish;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
box.write(BoxName.lang, langcode);
|
box.write(BoxName.lang, langcode);
|
||||||
// box.write(BoxName.lang, langcode);
|
|
||||||
Get.changeTheme(appTheme);
|
Get.changeTheme(appTheme);
|
||||||
Get.updateLocale(locale);
|
Get.updateLocale(locale);
|
||||||
restartApp();
|
restartApp();
|
||||||
@@ -94,62 +80,15 @@ class LocaleController extends GetxController {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
String storedLang = box.read(BoxName.lang) ?? "ar";
|
String? storedLang = box.read(BoxName.lang);
|
||||||
switch (storedLang) {
|
if (storedLang == null) {
|
||||||
case "ar":
|
// Use device language if no language is stored
|
||||||
language = const Locale("ar");
|
storedLang = Get.deviceLocale!.languageCode;
|
||||||
appTheme = themeArabic;
|
box.write(BoxName.lang, storedLang);
|
||||||
break;
|
|
||||||
case "en":
|
|
||||||
language = const Locale("en");
|
|
||||||
appTheme = themeEnglish;
|
|
||||||
break;
|
|
||||||
case "tr":
|
|
||||||
language = const Locale("tr");
|
|
||||||
appTheme = themeEnglish;
|
|
||||||
break;
|
|
||||||
case "fr":
|
|
||||||
language = const Locale("fr");
|
|
||||||
appTheme = themeEnglish;
|
|
||||||
break;
|
|
||||||
case "it":
|
|
||||||
language = const Locale("it");
|
|
||||||
appTheme = themeEnglish;
|
|
||||||
break;
|
|
||||||
case "de":
|
|
||||||
language = const Locale("de");
|
|
||||||
appTheme = themeEnglish;
|
|
||||||
break;
|
|
||||||
case "el":
|
|
||||||
language = const Locale("el");
|
|
||||||
appTheme = themeEnglish;
|
|
||||||
break;
|
|
||||||
case "es":
|
|
||||||
language = const Locale("es");
|
|
||||||
appTheme = themeEnglish;
|
|
||||||
break;
|
|
||||||
case "fa":
|
|
||||||
language = const Locale("fa");
|
|
||||||
appTheme = themeArabic;
|
|
||||||
break;
|
|
||||||
case "zh":
|
|
||||||
language = const Locale("zh");
|
|
||||||
appTheme = themeEnglish;
|
|
||||||
break;
|
|
||||||
case "ru":
|
|
||||||
language = const Locale("ru");
|
|
||||||
appTheme = themeEnglish;
|
|
||||||
break;
|
|
||||||
case "hi":
|
|
||||||
language = const Locale("hi");
|
|
||||||
appTheme = themeEnglish;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
language = Locale(Get.deviceLocale!.languageCode);
|
|
||||||
appTheme = themeEnglish;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
changeLang(storedLang);
|
||||||
|
|
||||||
super.onInit();
|
super.onInit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,13 +52,18 @@ class MyTranslation extends Translations {
|
|||||||
"Pick or Tap to confirm": "حدد أو انقر للتأكيد",
|
"Pick or Tap to confirm": "حدد أو انقر للتأكيد",
|
||||||
"Select Order Type": "حدد نوع الطلب",
|
"Select Order Type": "حدد نوع الطلب",
|
||||||
"Choose who this order is for": "اختر لمن هذا الطلب",
|
"Choose who this order is for": "اختر لمن هذا الطلب",
|
||||||
|
"Order Accepted": "تم قبول الطلب", "with type": "مع النوع",
|
||||||
|
"accepted your order at price": "قبل طلبك بالسعر",
|
||||||
"I want to order for myself": "أريد أن أطلب لنفسي",
|
"I want to order for myself": "أريد أن أطلب لنفسي",
|
||||||
"I want to order for someone else": "أريد أن أطلب لشخص آخر",
|
"I want to order for someone else": "أريد أن أطلب لشخص آخر",
|
||||||
"Cancel Trip from driver": "إلغاء الرحلة من السائق",
|
"Cancel Trip from driver": "إلغاء الرحلة من السائق",
|
||||||
|
"Order Cancelled": "تم إلغاء الطلب",
|
||||||
|
"you canceled order": "لقد قمت بإلغاء الطلب",
|
||||||
"If you want order to another person": "إذا كنت تريد الطلب لشخص آخر",
|
"If you want order to another person": "إذا كنت تريد الطلب لشخص آخر",
|
||||||
"Ok I will go now.": "حسنًا، سأذهب الآن.",
|
"Ok I will go now.": "حسنًا، سأذهب الآن.",
|
||||||
"Hi, I will go now": "مرحبًا، سأذهب الآن.",
|
"Hi, I will go now": "مرحبًا، سأذهب الآن.",
|
||||||
"upgrade price": "رفع السعر",
|
"upgrade price": "رفع السعر",
|
||||||
|
'Please enter a correct phone': 'يرجى إدخال رقم هاتف صحيح',
|
||||||
'airport': 'مطار',
|
'airport': 'مطار',
|
||||||
"Best choice for a comfortable car with a flexible route and stop points. This airport offers visa entry at this price.":
|
"Best choice for a comfortable car with a flexible route and stop points. This airport offers visa entry at this price.":
|
||||||
"أفضل اختيار لسيارة مريحة مع طريق ونقاط توقف مرنة. يقدم هذا المطار تأشيرة دخول بهذا السعر.",
|
"أفضل اختيار لسيارة مريحة مع طريق ونقاط توقف مرنة. يقدم هذا المطار تأشيرة دخول بهذا السعر.",
|
||||||
|
|||||||
@@ -699,7 +699,8 @@ class PaymentController extends GetxController {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// if (response!.success == true && response.responseCode == '200') {
|
// if (response!.success == true && response.responseCode == '200') {
|
||||||
if (response!.responseCode == '200' && response.success == true) {
|
if (response!.responseCode.toString() == '200' &&
|
||||||
|
response.success == true) {
|
||||||
// Log.print('transactionID wewer: ${response.transactionID}');
|
// Log.print('transactionID wewer: ${response.transactionID}');
|
||||||
Toast.show(context, 'Payment Successful'.tr, AppColor.greenColor);
|
Toast.show(context, 'Payment Successful'.tr, AppColor.greenColor);
|
||||||
method();
|
method();
|
||||||
|
|||||||
@@ -45,18 +45,6 @@ void main() async {
|
|||||||
// if (Platform.isAndroid) {
|
// if (Platform.isAndroid) {
|
||||||
NotificationController notificationController =
|
NotificationController notificationController =
|
||||||
Get.put(NotificationController());
|
Get.put(NotificationController());
|
||||||
await notificationController.initNotifications();
|
|
||||||
|
|
||||||
// Generate a random index to pick a message
|
|
||||||
final random = Random();
|
|
||||||
final randomMessage = messages[random.nextInt(messages.length)];
|
|
||||||
|
|
||||||
// Schedule the notification with the random message
|
|
||||||
notificationController.scheduleDailyNotifications(
|
|
||||||
randomMessage.split(':')[0],
|
|
||||||
randomMessage.split(':')[1],
|
|
||||||
"ding",
|
|
||||||
);
|
|
||||||
|
|
||||||
// await NotificationController().initNotifications();
|
// await NotificationController().initNotifications();
|
||||||
// }
|
// }
|
||||||
@@ -100,13 +88,18 @@ void main() async {
|
|||||||
userTokenExpiration: 200,
|
userTokenExpiration: 200,
|
||||||
iFrameID: 837992,
|
iFrameID: 837992,
|
||||||
);
|
);
|
||||||
// Get device information
|
await notificationController.initNotifications();
|
||||||
// List<Map<String, dynamic>> deviceDataList =
|
|
||||||
// await DeviceInfoPlus.getDeviceInfo();
|
|
||||||
//
|
|
||||||
// // Print all device data
|
|
||||||
// DeviceInfoPlus.printDeviceInfo();
|
|
||||||
|
|
||||||
|
// Generate a random index to pick a message
|
||||||
|
final random = Random();
|
||||||
|
final randomMessage = messages[random.nextInt(messages.length)];
|
||||||
|
|
||||||
|
// Schedule the notification with the random message
|
||||||
|
notificationController.scheduleNotificationsForSevenDays(
|
||||||
|
randomMessage.split(':')[0],
|
||||||
|
randomMessage.split(':')[1],
|
||||||
|
"tone1",
|
||||||
|
);
|
||||||
runApp(const MyApp());
|
runApp(const MyApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import '../../../constant/box_name.dart';
|
|||||||
import '../../../constant/colors.dart';
|
import '../../../constant/colors.dart';
|
||||||
import '../../../controller/home/profile/invit_controller.dart';
|
import '../../../controller/home/profile/invit_controller.dart';
|
||||||
import '../../../main.dart';
|
import '../../../main.dart';
|
||||||
|
import '../../../print.dart';
|
||||||
|
|
||||||
class ShareAppPage extends StatelessWidget {
|
class ShareAppPage extends StatelessWidget {
|
||||||
final InviteController controller = Get.put(InviteController());
|
final InviteController controller = Get.put(InviteController());
|
||||||
@@ -81,6 +82,40 @@ class ShareAppPage extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Widget _buildPhoneInput() {
|
||||||
|
// return Container(
|
||||||
|
// decoration: BoxDecoration(
|
||||||
|
// color: CupertinoColors.systemGrey6,
|
||||||
|
// borderRadius: BorderRadius.circular(8),
|
||||||
|
// ),
|
||||||
|
// child: Row(
|
||||||
|
// children: [
|
||||||
|
// Expanded(
|
||||||
|
// child: CupertinoTextField.borderless(
|
||||||
|
// controller: controller.invitePhoneController,
|
||||||
|
// placeholder: 'Enter phone'.tr,
|
||||||
|
// padding: const EdgeInsets.all(12),
|
||||||
|
// keyboardType: TextInputType.phone,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// CupertinoButton(
|
||||||
|
// child: const Icon(CupertinoIcons.person_badge_plus,
|
||||||
|
// color: AppColor.blueColor),
|
||||||
|
// onPressed: () async {
|
||||||
|
// await controller.pickContacts();
|
||||||
|
// if (controller.contacts.isNotEmpty) {
|
||||||
|
// if (box.read(BoxName.isSavedPhones) == null) {
|
||||||
|
// controller.savePhoneToServer();
|
||||||
|
// box.write(BoxName.isSavedPhones, true);
|
||||||
|
// }
|
||||||
|
// _showContactsDialog(Get.context!);
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
Widget _buildPhoneInput() {
|
Widget _buildPhoneInput() {
|
||||||
return Container(
|
return Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@@ -102,12 +137,15 @@ class ShareAppPage extends StatelessWidget {
|
|||||||
color: AppColor.blueColor),
|
color: AppColor.blueColor),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await controller.pickContacts();
|
await controller.pickContacts();
|
||||||
|
Log.print('contacts: ${controller.contacts}');
|
||||||
if (controller.contacts.isNotEmpty) {
|
if (controller.contacts.isNotEmpty) {
|
||||||
if (box.read(BoxName.isSavedPhones) == null) {
|
_showContactsDialog(Get
|
||||||
controller.savePhoneToServer();
|
.context!); // Show contacts dialog after loading contacts
|
||||||
box.write(BoxName.isSavedPhones, true);
|
} else {
|
||||||
}
|
Get.snackbar(
|
||||||
_showContactsDialog(Get.context!);
|
'No contacts available'.tr,
|
||||||
|
'Please add contacts to your phone.'.tr,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -326,48 +364,38 @@ class ShareAppPage extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _showContactsDialog(BuildContext context) {
|
void _showContactsDialog(BuildContext context) {
|
||||||
showCupertinoModalPopup(
|
Get.defaultDialog(
|
||||||
context: context,
|
title: 'Choose from contact'.tr,
|
||||||
builder: (BuildContext context) => Container(
|
content: SizedBox(
|
||||||
height: 400,
|
height: 400,
|
||||||
decoration: BoxDecoration(
|
width: 400,
|
||||||
color: CupertinoColors.systemBackground,
|
|
||||||
borderRadius: const BorderRadius.vertical(top: Radius.circular(20)),
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: CupertinoColors.black.withOpacity(0.2),
|
|
||||||
offset: const Offset(0, -4),
|
|
||||||
blurRadius: 10,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
// Header with cancel and title
|
// Header with cancel and title
|
||||||
Container(
|
// Container(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
// padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||||
decoration: const BoxDecoration(
|
// decoration: const BoxDecoration(
|
||||||
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
|
// borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
|
||||||
color: CupertinoColors.systemGrey6,
|
// color: CupertinoColors.systemGrey6,
|
||||||
),
|
// ),
|
||||||
child: Row(
|
// child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
// children: [
|
||||||
CupertinoButton(
|
// CupertinoButton(
|
||||||
padding: EdgeInsets.zero,
|
// padding: EdgeInsets.zero,
|
||||||
child: Text(
|
// child: Text(
|
||||||
'Cancel'.tr,
|
// 'Cancel'.tr,
|
||||||
style: const TextStyle(color: CupertinoColors.systemBlue),
|
// style: const TextStyle(color: CupertinoColors.systemBlue),
|
||||||
),
|
// ),
|
||||||
onPressed: () => Navigator.pop(context),
|
// onPressed: () => Navigator.pop(context),
|
||||||
),
|
// ),
|
||||||
Container(
|
// Container(
|
||||||
child: Text('Choose from contact'.tr,
|
// child: Text('Choose from contact'.tr,
|
||||||
style: AppStyle.title)),
|
// style: AppStyle.title)),
|
||||||
const SizedBox(width: 60), // Balance for Cancel button
|
// const SizedBox(width: 60), // Balance for Cancel button
|
||||||
],
|
// ],
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
|
|
||||||
// Contact list
|
// Contact list
|
||||||
Expanded(
|
Expanded(
|
||||||
@@ -433,5 +461,112 @@ class ShareAppPage extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
// showCupertinoModalPopup(
|
||||||
|
// context: context,
|
||||||
|
// builder: (BuildContext context) => Container(
|
||||||
|
// height: 400,
|
||||||
|
// decoration: BoxDecoration(
|
||||||
|
// color: CupertinoColors.systemBackground,
|
||||||
|
// borderRadius: const BorderRadius.vertical(top: Radius.circular(20)),
|
||||||
|
// boxShadow: [
|
||||||
|
// BoxShadow(
|
||||||
|
// color: CupertinoColors.black.withOpacity(0.2),
|
||||||
|
// offset: const Offset(0, -4),
|
||||||
|
// blurRadius: 10,
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// child: Column(
|
||||||
|
// children: [
|
||||||
|
// // Header with cancel and title
|
||||||
|
// Container(
|
||||||
|
// padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||||
|
// decoration: const BoxDecoration(
|
||||||
|
// borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
|
||||||
|
// color: CupertinoColors.systemGrey6,
|
||||||
|
// ),
|
||||||
|
// child: Row(
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
// children: [
|
||||||
|
// CupertinoButton(
|
||||||
|
// padding: EdgeInsets.zero,
|
||||||
|
// child: Text(
|
||||||
|
// 'Cancel'.tr,
|
||||||
|
// style: const TextStyle(color: CupertinoColors.systemBlue),
|
||||||
|
// ),
|
||||||
|
// onPressed: () => Navigator.pop(context),
|
||||||
|
// ),
|
||||||
|
// Container(
|
||||||
|
// child: Text('Choose from contact'.tr,
|
||||||
|
// style: AppStyle.title)),
|
||||||
|
// const SizedBox(width: 60), // Balance for Cancel button
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
|
||||||
|
// // Contact list
|
||||||
|
// Expanded(
|
||||||
|
// child: ListView.builder(
|
||||||
|
// itemCount: controller.contactMaps.length,
|
||||||
|
// itemBuilder: (context, index) {
|
||||||
|
// final contact = controller.contactMaps[index];
|
||||||
|
// return CupertinoButton(
|
||||||
|
// padding: EdgeInsets.zero,
|
||||||
|
// onPressed: () {
|
||||||
|
// controller.selectPhone(contact['phones'].toString());
|
||||||
|
// },
|
||||||
|
// child: Container(
|
||||||
|
// padding: const EdgeInsets.symmetric(
|
||||||
|
// horizontal: 16, vertical: 12),
|
||||||
|
// decoration: BoxDecoration(
|
||||||
|
// color: CupertinoColors.systemBackground,
|
||||||
|
// border: Border(
|
||||||
|
// bottom: BorderSide(
|
||||||
|
// color: CupertinoColors.separator.withOpacity(0.5),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// child: Row(
|
||||||
|
// children: [
|
||||||
|
// // Display contact name and phone number
|
||||||
|
// Expanded(
|
||||||
|
// child: Column(
|
||||||
|
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
// children: [
|
||||||
|
// Text(
|
||||||
|
// contact['name'],
|
||||||
|
// style: const TextStyle(
|
||||||
|
// color: CupertinoColors.label,
|
||||||
|
// fontSize: 17,
|
||||||
|
// fontWeight: FontWeight.w500,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// Text(
|
||||||
|
// controller.formatPhoneNumber(
|
||||||
|
// contact['phones'][0].toString()),
|
||||||
|
// style: const TextStyle(
|
||||||
|
// color: CupertinoColors.secondaryLabel,
|
||||||
|
// fontSize: 15,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// // Chevron icon for selection
|
||||||
|
// const Icon(
|
||||||
|
// CupertinoIcons.chevron_forward,
|
||||||
|
// color: CupertinoColors.systemGrey2,
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,15 +97,7 @@ GetBuilder<MapPassengerController> leftMainMenuIcons() {
|
|||||||
// borderRadius: BorderRadius.circular(15)),
|
// borderRadius: BorderRadius.circular(15)),
|
||||||
// child: IconButton(
|
// child: IconButton(
|
||||||
// onPressed: () async {
|
// onPressed: () async {
|
||||||
// final random = Random();
|
// Get.to(SmsSignupEgypt());
|
||||||
// final randomMessage =
|
|
||||||
// messages[random.nextInt(messages.length)];
|
|
||||||
// NotificationController().showNotification(
|
|
||||||
// randomMessage.split(':')[0],
|
|
||||||
// randomMessage.split(':')[1],
|
|
||||||
// "ding",
|
|
||||||
// );
|
|
||||||
// print(box.read(BoxName.countryCode).toString());
|
|
||||||
// },
|
// },
|
||||||
// icon: const Icon(
|
// icon: const Icon(
|
||||||
// Icons.voice_chat,
|
// Icons.voice_chat,
|
||||||
|
|||||||
69
lib/views/widgets/mysnakbar.dart
Normal file
69
lib/views/widgets/mysnakbar.dart
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
import '../../constant/colors.dart';
|
||||||
|
|
||||||
|
SnackbarController mySnackeBarError(String message) {
|
||||||
|
return Get.snackbar(
|
||||||
|
'Error'.tr,
|
||||||
|
message,
|
||||||
|
backgroundColor: AppColor.redColor.withOpacity(0.9),
|
||||||
|
colorText: AppColor.secondaryColor,
|
||||||
|
icon: const Icon(Icons.error, color: AppColor.secondaryColor),
|
||||||
|
shouldIconPulse: true,
|
||||||
|
snackPosition: SnackPosition.TOP,
|
||||||
|
margin: const EdgeInsets.all(10),
|
||||||
|
borderRadius: 10,
|
||||||
|
animationDuration: const Duration(milliseconds: 500),
|
||||||
|
forwardAnimationCurve: Curves.easeOutBack,
|
||||||
|
reverseAnimationCurve: Curves.easeInBack,
|
||||||
|
titleText: Text(
|
||||||
|
'Error'.tr,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
messageText: Text(
|
||||||
|
message,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white.withOpacity(0.9),
|
||||||
|
fontSize: 14,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
SnackbarController mySnackbarSuccess(String message) {
|
||||||
|
return Get.snackbar(
|
||||||
|
'Success'.tr,
|
||||||
|
message,
|
||||||
|
backgroundColor: AppColor.greenColor
|
||||||
|
.withOpacity(0.9), // Assuming green color for success
|
||||||
|
colorText: AppColor.secondaryColor,
|
||||||
|
icon: const Icon(Icons.check_circle, color: AppColor.secondaryColor),
|
||||||
|
shouldIconPulse: true,
|
||||||
|
snackPosition: SnackPosition.TOP,
|
||||||
|
margin: const EdgeInsets.all(10),
|
||||||
|
borderRadius: 10,
|
||||||
|
animationDuration: const Duration(milliseconds: 500),
|
||||||
|
forwardAnimationCurve: Curves.easeOutBack,
|
||||||
|
reverseAnimationCurve: Curves.easeInBack,
|
||||||
|
titleText: Text(
|
||||||
|
'Success'.tr,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
messageText: Text(
|
||||||
|
message,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white.withOpacity(0.9),
|
||||||
|
fontSize: 14,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user