diff --git a/.env b/.env
index 00e0d01..60ffc61 100644
--- a/.env
+++ b/.env
@@ -5,6 +5,7 @@ accountSIDTwillo=QFx0qy456juj3839xuy2194q629q1fj0y7XrXlBl
serverAPI=QQQQobSrrFi:QVQ87xU7zwCvmZzZdaxuS2f23Y4mz7MzyOzr8od2br6KYyeFaTVLG3K3hx5ZaUyx7eYvAYpAVdKk-286NTRi3zs9iSOnXtXRIxswg3KecBmsl3VxJ9wO-vIpwu4Pv7dkHkXniuxMSDgWXrXlBl
mapAPIKEY=QOmqZsFsutLDCtZCRIUAZAkB5v6AMkKEPMbJGa3XrXlBl
twilloRecoveryCode=CAU79DHPH1BE9PUH4ETXTSXZXrXlBl
+apiKeyHere=g_WNUb5L-7-F8oHpUmgIzH7ETeH9xZ8RwGG9_G8zX9A
authTokenTwillo=70u98ju0214xx4q0u74028u021u4qu65XrXlBl
chatGPTkey=zg-4C26q4SYBKQeHZDqkWowC9XrxgUEfUy9JRw2rm6Q2adb3kjwXrXlBl
transactionCloude=Qhcwilomqcoib:QVO_JNYED2XWA26YXKC2TP:YK1DVH6SJB31N3PE1UXrXlBl
@@ -18,9 +19,9 @@ serverPHP=https://api.sefer.live/sefer
seferAlexandriaServer=https://seferalexandria.site/sefer
seferPaymentServer=https://seferpw.shop/sefer
seferCairoServer=https://sefer.click/sefer
-seferGizaServer=https://sefergiza.site/sefer
+seferGizaServer=https://gizasefer.online/sefer
whatappID=369939736211879
-whatsapp=EEAAOtbZBSUK74BO93qYEsBTetiT5qGCHCdxDRXEH1cGUrlbHN2ZB4bVrFCR1ZC8xEVDtHeLUH6yHej2RPMpmoLD69AlqBJJDtQ7nrsmbeIRZCBGPoKueLQUaEMWPC2R6EJdZArqdFy1rv4ZAGJZBV9ifxvwwTAlw7dbzA3WEZBvWKPXswUkPP9UWM1fWEPL86buyH0IvEd6j9grk6l7rG6CAZD
+whatsapp=EAAOtbZBSUK74BO6yE1QwIBsRCjPDANdum66xap0ZA7OZA8LqEu8MZAts1kwr12eRiNXtvpJ2ZAFSY5dw3KVSyrUuH8boLjynxdFI4Gh1Q7BCHx275X2uZBwKWZCSrsVN17i6mZAFNYYd25sQv0ZBomeTk02ZCIJot4UqWxK9ZBvxsq1k2yS7lD2NsjZB5EHbpaYGLzxFJ2FCCSX6iHyKXab6ckfK7m19wo77in7Dl3YZD
cohere=Aulwd8y5SPWos0hJhG0toUf8gOhUUrpf5Q2TPmVGXrXlBl
claudeAiAPI=zg-qbc-qvo39-xWOxIGwWTOzCFBnIYSKKhfyz_KVAvrH-6_4ZEJL68G_QBH26oeTOMMoQug9KuOjjKSP_A4S3SUDlbxR9duVzoQ-MkX_UQQQXrXlBl
payPalClientId=QALymfNI5Tzt4s-ysoz6vD4_nqX0SUtkC_qYV-Ugk5gaM_8Z-kg4L53k8Uux_4jEWXDkNpXGSWPpIzDFXrXlBl
diff --git a/Archive.zip b/Archive.zip
new file mode 100644
index 0000000..e9eafde
Binary files /dev/null and b/Archive.zip differ
diff --git a/android/app/build.gradle b/android/app/build.gradle
index e3cd72a..f30629a 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -26,18 +26,24 @@ apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
// apply plugin: 'com.google.gms.google-services'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
+
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
-
+if (keystorePropertiesFile.exists()) {
+ keystorePropertiesFile.withReader('UTF-8') { reader ->
+ keystoreProperties.load(reader)
+ }
+}
android {
namespace "com.mobileapp.store.ride"
- compileSdkVersion 34
- ndkVersion flutter.ndkVersion
+ compileSdk 35
+ ndkVersion "26.1.10909125"
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
+ coreLibraryDesugaringEnabled true
}
kotlinOptions {
@@ -49,33 +55,45 @@ android {
}
defaultConfig {
- // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
- applicationId "com.mobileapp.store.ride"
+ // Specify your unique Application ID
+ applicationId = "com.mobileapp.store.ride"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
+<<<<<<< HEAD
minSdkVersion 23
targetSdkVersion 34
versionCode 65
versionName '1.5.65'
multiDexEnabled =true
// manifestPlaceholders = [mapsApiKey: 'android/app/src/main/AndroidManifest.xml']
+=======
+ minSdk = 23
+ targetSdk = flutter.targetSdkVersion
+ versionCode = 108
+ versionName = '1.6.108'
+ multiDexEnabled =true
+
+ // manifestPlaceholders can be specified here if needed
+>>>>>>> 8813b4d
}
- signingConfigs {
- release {
- keyAlias keystoreProperties['keyAlias']
- keyPassword keystoreProperties['keyPassword']
- storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
- storePassword keystoreProperties['storePassword']
- }
- }
- buildTypes {
- release {
- signingConfig signingConfigs.release
- }
- }
+ signingConfigs {
+ release {
+ keyAlias keystoreProperties['keyAlias']
+ keyPassword keystoreProperties['keyPassword']
+ storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
+ storePassword keystoreProperties['storePassword']
+ }
+ }
-
+ buildTypes {
+ release {
+ signingConfig signingConfigs.release
+// minifyEnabled true
+// shrinkResources true
+// proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
}
flutter {
@@ -84,6 +102,14 @@ flutter {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+ coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.2.2'
+ // Optional dependencies like Firebase can be uncommented if needed
// implementation platform('com.google.firebase:firebase-bom:32.1.1')
-
-}
+ implementation "com.stripe:stripe-android:20.47.0"
+ implementation 'com.stripe:paymentsheet:20.47.0'
+
+
+ // If push provisioning is needed, make sure you have the correct version:
+// implementation "com.stripe:stripe-android-pushprovisioning:VERSION" // Replace VERSION with the correct one.
+
+}
\ No newline at end of file
diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro
new file mode 100644
index 0000000..ef62132
--- /dev/null
+++ b/android/app/proguard-rules.pro
@@ -0,0 +1,30 @@
+# Suppress warnings for specific Google ML Kit and Stripe classes
+-dontwarn com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions$Builder
+-dontwarn com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions
+-dontwarn com.google.mlkit.vision.text.devanagari.DevanagariTextRecognizerOptions$Builder
+-dontwarn com.google.mlkit.vision.text.devanagari.DevanagariTextRecognizerOptions
+-dontwarn com.google.mlkit.vision.text.japanese.JapaneseTextRecognizerOptions$Builder
+-dontwarn com.google.mlkit.vision.text.japanese.JapaneseTextRecognizerOptions
+-dontwarn com.google.mlkit.vision.text.korean.KoreanTextRecognizerOptions$Builder
+-dontwarn com.google.mlkit.vision.text.korean.KoreanTextRecognizerOptions
+-dontwarn com.stripe.android.pushProvisioning.PushProvisioningActivity$g
+-dontwarn com.stripe.android.pushProvisioning.PushProvisioningActivityStarter$Args
+-dontwarn com.stripe.android.pushProvisioning.PushProvisioningActivityStarter$Error
+-dontwarn com.stripe.android.pushProvisioning.PushProvisioningActivityStarter
+-dontwarn com.stripe.android.pushProvisioning.PushProvisioningEphemeralKeyProvider
+
+# Keep rules for Google ML Kit
+-keep class com.google.mlkit.vision.** { *; }
+-keep class com.google.mlkit.vision.text.** { *; }
+-keep class com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions { *; }
+-keep class com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions$Builder { *; }
+-keep class com.google.mlkit.vision.text.devanagari.DevanagariTextRecognizerOptions { *; }
+-keep class com.google.mlkit.vision.text.devanagari.DevanagariTextRecognizerOptions$Builder { *; }
+-keep class com.google.mlkit.vision.text.japanese.JapaneseTextRecognizerOptions { *; }
+-keep class com.google.mlkit.vision.text.japanese.JapaneseTextRecognizerOptions$Builder { *; }
+-keep class com.google.mlkit.vision.text.korean.KoreanTextRecognizerOptions { *; }
+-keep class com.google.mlkit.vision.text.korean.KoreanTextRecognizerOptions$Builder { *; }
+
+# Keep rules for Stripe
+-keep class com.stripe.android.** { *; }
+-keep class com.stripe.android.pushProvisioning.** { *; }
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index fedcf91..cbffd52 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -10,6 +10,12 @@
+
+
+
+
+
+
@@ -25,6 +31,7 @@
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
+ android:enableOnBackInvokedCallback="true"
android:windowSoftInputMode="adjustResize">
+
+
+
+
+
+
+
+
+
My App
- default_channel
+
+ high_importance_channel
AIzaSyCyfwRXTwSTLOFQSQgN5p7QZgGJVZnEKq0
\ No newline at end of file
diff --git a/android/build.gradle b/android/build.gradle
index 6f00cdb..eccf533 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -12,7 +12,7 @@ buildscript {
// classpath 'com.android.tools.build:gradle:7.3.1'
classpath 'com.google.gms:google-services:4.3.15'
// END: FlutterFire Configuration
- classpath 'com.android.tools.build:gradle:7.3.0'
+ classpath 'com.android.tools.build:gradle:8.4.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
diff --git a/android/gradle.properties b/android/gradle.properties
index 4de64f2..91ed4fe 100644
--- a/android/gradle.properties
+++ b/android/gradle.properties
@@ -1,3 +1,6 @@
org.gradle.jvmargs=-Xmx4096M
android.useAndroidX=true
android.enableJetifier=true
+android.defaults.buildfeatures.buildconfig=true
+android.nonTransitiveRClass=false
+android.nonFinalResIds=false
diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties
index 2443e72..684137a 100644
--- a/android/gradle/wrapper/gradle-wrapper.properties
+++ b/android/gradle/wrapper/gradle-wrapper.properties
@@ -4,4 +4,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-all.zip
diff --git a/assets/images/car3.png b/assets/images/car3.png
new file mode 100644
index 0000000..41627ae
Binary files /dev/null and b/assets/images/car3.png differ
diff --git a/assets/images/moto.png b/assets/images/moto.png
index 0cb9559..8257812 100644
Binary files a/assets/images/moto.png and b/assets/images/moto.png differ
diff --git a/assets/images/pinkBike.png b/assets/images/pinkBike.png
new file mode 100644
index 0000000..0ed4ec5
Binary files /dev/null and b/assets/images/pinkBike.png differ
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index 2de2cf2..7975ed8 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -9,54 +9,61 @@ PODS:
- Flutter
- device_info_plus (0.0.1):
- Flutter
- - Firebase/Auth (10.28.0):
+ - Firebase/Auth (11.0.0):
- Firebase/CoreOnly
- - FirebaseAuth (~> 10.28.0)
- - Firebase/CoreOnly (10.28.0):
- - FirebaseCore (= 10.28.0)
- - Firebase/Messaging (10.28.0):
+ - FirebaseAuth (~> 11.0.0)
+ - Firebase/CoreOnly (11.0.0):
+ - FirebaseCore (= 11.0.0)
+ - Firebase/Messaging (11.0.0):
- Firebase/CoreOnly
- - FirebaseMessaging (~> 10.28.0)
- - firebase_auth (5.1.2):
- - Firebase/Auth (= 10.28.0)
+ - FirebaseMessaging (~> 11.0.0)
+ - firebase_auth (5.2.0):
+ - Firebase/Auth (= 11.0.0)
- firebase_core
- Flutter
- - firebase_core (3.2.0):
- - Firebase/CoreOnly (= 10.28.0)
+ - firebase_core (3.4.0):
+ - Firebase/CoreOnly (= 11.0.0)
- Flutter
- - firebase_messaging (15.0.3):
- - Firebase/Messaging (= 10.28.0)
+ - firebase_messaging (15.1.0):
+ - Firebase/Messaging (= 11.0.0)
- firebase_core
- Flutter
- - FirebaseAppCheckInterop (10.29.0)
- - FirebaseAuth (10.28.0):
- - FirebaseAppCheckInterop (~> 10.17)
- - FirebaseCore (~> 10.0)
- - GoogleUtilities/AppDelegateSwizzler (~> 7.8)
- - GoogleUtilities/Environment (~> 7.8)
- - GTMSessionFetcher/Core (< 4.0, >= 2.1)
+ - FirebaseAppCheckInterop (11.5.0)
+ - FirebaseAuth (11.0.0):
+ - FirebaseAppCheckInterop (~> 11.0)
+ - FirebaseAuthInterop (~> 11.0)
+ - FirebaseCore (~> 11.0)
+ - FirebaseCoreExtension (~> 11.0)
+ - GoogleUtilities/AppDelegateSwizzler (~> 8.0)
+ - GoogleUtilities/Environment (~> 8.0)
+ - GTMSessionFetcher/Core (~> 3.4)
- RecaptchaInterop (~> 100.0)
- - FirebaseCore (10.28.0):
- - FirebaseCoreInternal (~> 10.0)
- - GoogleUtilities/Environment (~> 7.12)
- - GoogleUtilities/Logger (~> 7.12)
- - FirebaseCoreInternal (10.29.0):
- - "GoogleUtilities/NSData+zlib (~> 7.8)"
- - FirebaseInstallations (10.29.0):
- - FirebaseCore (~> 10.0)
- - GoogleUtilities/Environment (~> 7.8)
- - GoogleUtilities/UserDefaults (~> 7.8)
- - PromisesObjC (~> 2.1)
- - FirebaseMessaging (10.28.0):
- - FirebaseCore (~> 10.0)
- - FirebaseInstallations (~> 10.0)
- - GoogleDataTransport (~> 9.3)
- - GoogleUtilities/AppDelegateSwizzler (~> 7.8)
- - GoogleUtilities/Environment (~> 7.8)
- - GoogleUtilities/Reachability (~> 7.8)
- - GoogleUtilities/UserDefaults (~> 7.8)
- - nanopb (< 2.30911.0, >= 2.30908.0)
+ - FirebaseAuthInterop (11.5.0)
+ - FirebaseCore (11.0.0):
+ - FirebaseCoreInternal (~> 11.0)
+ - GoogleUtilities/Environment (~> 8.0)
+ - GoogleUtilities/Logger (~> 8.0)
+ - FirebaseCoreExtension (11.4.1):
+ - FirebaseCore (~> 11.0)
+ - FirebaseCoreInternal (11.5.0):
+ - "GoogleUtilities/NSData+zlib (~> 8.0)"
+ - FirebaseInstallations (11.4.0):
+ - FirebaseCore (~> 11.0)
+ - GoogleUtilities/Environment (~> 8.0)
+ - GoogleUtilities/UserDefaults (~> 8.0)
+ - PromisesObjC (~> 2.4)
+ - FirebaseMessaging (11.0.0):
+ - FirebaseCore (~> 11.0)
+ - FirebaseInstallations (~> 11.0)
+ - GoogleDataTransport (~> 10.0)
+ - GoogleUtilities/AppDelegateSwizzler (~> 8.0)
+ - GoogleUtilities/Environment (~> 8.0)
+ - GoogleUtilities/Reachability (~> 8.0)
+ - GoogleUtilities/UserDefaults (~> 8.0)
+ - nanopb (~> 3.30910.0)
- Flutter (1.0.0)
+ - flutter_contacts (0.0.1):
+ - Flutter
- flutter_local_notifications (0.0.1):
- Flutter
- flutter_secure_storage (6.0.0):
@@ -65,8 +72,11 @@ PODS:
- Flutter
- geolocator_apple (1.2.0):
- Flutter
+ - Google-Maps-iOS-Utils (5.0.0):
+ - GoogleMaps (~> 8.0)
- google_maps_flutter_ios (0.0.1):
- Flutter
+ - Google-Maps-iOS-Utils (< 7.0, >= 5.0)
- GoogleMaps (< 10.0, >= 8.4)
- google_sign_in_ios (0.0.1):
- AppAuth (>= 1.7.4)
@@ -74,10 +84,9 @@ PODS:
- FlutterMacOS
- GoogleSignIn (~> 7.1)
- GTMSessionFetcher (>= 3.4.0)
- - GoogleDataTransport (9.4.1):
- - GoogleUtilities/Environment (~> 7.7)
- - nanopb (< 2.30911.0, >= 2.30908.0)
- - PromisesObjC (< 3.0, >= 1.2)
+ - GoogleDataTransport (10.1.0):
+ - nanopb (~> 3.30910.0)
+ - PromisesObjC (~> 2.4)
- GoogleMaps (8.4.0):
- GoogleMaps/Maps (= 8.4.0)
- GoogleMaps/Base (8.4.0)
@@ -87,29 +96,28 @@ PODS:
- AppAuth (< 2.0, >= 1.7.3)
- GTMAppAuth (< 5.0, >= 4.1.1)
- GTMSessionFetcher/Core (~> 3.3)
- - GoogleUtilities/AppDelegateSwizzler (7.13.3):
+ - GoogleUtilities/AppDelegateSwizzler (8.0.2):
- GoogleUtilities/Environment
- GoogleUtilities/Logger
- GoogleUtilities/Network
- GoogleUtilities/Privacy
- - GoogleUtilities/Environment (7.13.3):
+ - GoogleUtilities/Environment (8.0.2):
- GoogleUtilities/Privacy
- - PromisesObjC (< 3.0, >= 1.2)
- - GoogleUtilities/Logger (7.13.3):
+ - GoogleUtilities/Logger (8.0.2):
- GoogleUtilities/Environment
- GoogleUtilities/Privacy
- - GoogleUtilities/Network (7.13.3):
+ - GoogleUtilities/Network (8.0.2):
- GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib"
- GoogleUtilities/Privacy
- GoogleUtilities/Reachability
- - "GoogleUtilities/NSData+zlib (7.13.3)":
+ - "GoogleUtilities/NSData+zlib (8.0.2)":
- GoogleUtilities/Privacy
- - GoogleUtilities/Privacy (7.13.3)
- - GoogleUtilities/Reachability (7.13.3):
+ - GoogleUtilities/Privacy (8.0.2)
+ - GoogleUtilities/Reachability (8.0.2):
- GoogleUtilities/Logger
- GoogleUtilities/Privacy
- - GoogleUtilities/UserDefaults (7.13.3):
+ - GoogleUtilities/UserDefaults (8.0.2):
- GoogleUtilities/Logger
- GoogleUtilities/Privacy
- GTMAppAuth (4.1.1):
@@ -129,13 +137,14 @@ PODS:
- Flutter
- local_auth_darwin (0.0.1):
- Flutter
+ - FlutterMacOS
- location (0.0.1):
- Flutter
- - nanopb (2.30910.0):
- - nanopb/decode (= 2.30910.0)
- - nanopb/encode (= 2.30910.0)
- - nanopb/decode (2.30910.0)
- - nanopb/encode (2.30910.0)
+ - nanopb (3.30910.0):
+ - nanopb/decode (= 3.30910.0)
+ - nanopb/encode (= 3.30910.0)
+ - nanopb/decode (3.30910.0)
+ - nanopb/encode (3.30910.0)
- package_info_plus (0.4.5):
- Flutter
- path_provider_foundation (0.0.1):
@@ -155,42 +164,42 @@ PODS:
- sqflite (0.0.3):
- Flutter
- FlutterMacOS
- - Stripe (23.27.6):
- - StripeApplePay (= 23.27.6)
- - StripeCore (= 23.27.6)
- - StripePayments (= 23.27.6)
- - StripePaymentsUI (= 23.27.6)
- - StripeUICore (= 23.27.6)
+ - Stripe (23.28.3):
+ - StripeApplePay (= 23.28.3)
+ - StripeCore (= 23.28.3)
+ - StripePayments (= 23.28.3)
+ - StripePaymentsUI (= 23.28.3)
+ - StripeUICore (= 23.28.3)
- stripe_ios (0.0.1):
- Flutter
- - Stripe (~> 23.27.0)
- - StripeApplePay (~> 23.27.0)
- - StripeFinancialConnections (~> 23.27.0)
- - StripePayments (~> 23.27.0)
- - StripePaymentSheet (~> 23.27.0)
- - StripePaymentsUI (~> 23.27.0)
- - StripeApplePay (23.27.6):
- - StripeCore (= 23.27.6)
- - StripeCore (23.27.6)
- - StripeFinancialConnections (23.27.6):
- - StripeCore (= 23.27.6)
- - StripeUICore (= 23.27.6)
- - StripePayments (23.27.6):
- - StripeCore (= 23.27.6)
- - StripePayments/Stripe3DS2 (= 23.27.6)
- - StripePayments/Stripe3DS2 (23.27.6):
- - StripeCore (= 23.27.6)
- - StripePaymentSheet (23.27.6):
- - StripeApplePay (= 23.27.6)
- - StripeCore (= 23.27.6)
- - StripePayments (= 23.27.6)
- - StripePaymentsUI (= 23.27.6)
- - StripePaymentsUI (23.27.6):
- - StripeCore (= 23.27.6)
- - StripePayments (= 23.27.6)
- - StripeUICore (= 23.27.6)
- - StripeUICore (23.27.6):
- - StripeCore (= 23.27.6)
+ - Stripe (~> 23.28.0)
+ - StripeApplePay (~> 23.28.0)
+ - StripeFinancialConnections (~> 23.28.0)
+ - StripePayments (~> 23.28.0)
+ - StripePaymentSheet (~> 23.28.0)
+ - StripePaymentsUI (~> 23.28.0)
+ - StripeApplePay (23.28.3):
+ - StripeCore (= 23.28.3)
+ - StripeCore (23.28.3)
+ - StripeFinancialConnections (23.28.3):
+ - StripeCore (= 23.28.3)
+ - StripeUICore (= 23.28.3)
+ - StripePayments (23.28.3):
+ - StripeCore (= 23.28.3)
+ - StripePayments/Stripe3DS2 (= 23.28.3)
+ - StripePayments/Stripe3DS2 (23.28.3):
+ - StripeCore (= 23.28.3)
+ - StripePaymentSheet (23.28.3):
+ - StripeApplePay (= 23.28.3)
+ - StripeCore (= 23.28.3)
+ - StripePayments (= 23.28.3)
+ - StripePaymentsUI (= 23.28.3)
+ - StripePaymentsUI (23.28.3):
+ - StripeCore (= 23.28.3)
+ - StripePayments (= 23.28.3)
+ - StripeUICore (= 23.28.3)
+ - StripeUICore (23.28.3):
+ - StripeCore (= 23.28.3)
- TOCropViewController (2.7.4)
- uni_links (0.0.1):
- Flutter
@@ -205,6 +214,7 @@ PODS:
- Flutter
- webview_flutter_wkwebview (0.0.1):
- Flutter
+ - FlutterMacOS
DEPENDENCIES:
- audio_session (from `.symlinks/plugins/audio_session/ios`)
@@ -213,6 +223,7 @@ DEPENDENCIES:
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
- firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
- Flutter (from `Flutter`)
+ - flutter_contacts (from `.symlinks/plugins/flutter_contacts/ios`)
- flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`)
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
- flutter_tts (from `.symlinks/plugins/flutter_tts/ios`)
@@ -237,7 +248,7 @@ DEPENDENCIES:
- vibration (from `.symlinks/plugins/vibration/ios`)
- video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/darwin`)
- wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)
- - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`)
+ - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/darwin`)
SPEC REPOS:
trunk:
@@ -245,10 +256,13 @@ SPEC REPOS:
- Firebase
- FirebaseAppCheckInterop
- FirebaseAuth
+ - FirebaseAuthInterop
- FirebaseCore
+ - FirebaseCoreExtension
- FirebaseCoreInternal
- FirebaseInstallations
- FirebaseMessaging
+ - Google-Maps-iOS-Utils
- GoogleDataTransport
- GoogleMaps
- GoogleSignIn
@@ -281,6 +295,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/firebase_messaging/ios"
Flutter:
:path: Flutter
+ flutter_contacts:
+ :path: ".symlinks/plugins/flutter_contacts/ios"
flutter_local_notifications:
:path: ".symlinks/plugins/flutter_local_notifications/ios"
flutter_secure_storage:
@@ -330,41 +346,45 @@ EXTERNAL SOURCES:
wakelock_plus:
:path: ".symlinks/plugins/wakelock_plus/ios"
webview_flutter_wkwebview:
- :path: ".symlinks/plugins/webview_flutter_wkwebview/ios"
+ :path: ".symlinks/plugins/webview_flutter_wkwebview/darwin"
SPEC CHECKSUMS:
AppAuth: 501c04eda8a8d11f179dbe8637b7a91bb7e5d2fa
audio_session: 088d2483ebd1dc43f51d253d4a1c517d9a2e7207
device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d
- Firebase: 5121c624121af81cbc81df3bda414b3c28c4f3c3
- firebase_auth: e778ee89483b86fe4200d1f8e9a1c52aa5fb64a8
- firebase_core: a9d0180d5285527884d07a41eb4a9ec9ed12cdb6
- firebase_messaging: ccc82a143a74de75f440a4e413dbbb37ec3fddbc
- FirebaseAppCheckInterop: 6a1757cfd4067d8e00fccd14fcc1b8fd78cfac07
- FirebaseAuth: 3d872fbbfc4223edeb72769e488f325fa8b0a4a9
- FirebaseCore: 857dc1c6dd1255675047404d8466f7dfaac5d779
- FirebaseCoreInternal: df84dd300b561c27d5571684f389bf60b0a5c934
- FirebaseInstallations: 913cf60d0400ebd5d6b63a28b290372ab44590dd
- FirebaseMessaging: 087a7c7cadef7b9239f005bc4db823894844f323
+ Firebase: 9f574c08c2396885b5e7e100ed4293d956218af9
+ firebase_auth: 16ac5db3d064db837ecd845080d7e18e4be7c66d
+ firebase_core: ceec591a66629daaee82d3321551692c4a871493
+ firebase_messaging: 15d8b557010f3bb7b98d0302e1c7c8fbcd244425
+ FirebaseAppCheckInterop: d265d9f4484e7ec1c591086408840fdd383d1213
+ FirebaseAuth: d5cf28be74d7e82257f6a3f717509eff70d3cf4a
+ FirebaseAuthInterop: 1219bee9b23e6ebe84c256a0d95adab53d11c331
+ FirebaseCore: 3cf438f431f18c12cdf2aaf64434648b63f7e383
+ FirebaseCoreExtension: f1bc67a4702931a7caa097d8e4ac0a1b0d16720e
+ FirebaseCoreInternal: f47dd28ae7782e6a4738aad3106071a8fe0af604
+ FirebaseInstallations: 6ef4a1c7eb2a61ee1f74727d7f6ce2e72acf1414
+ FirebaseMessaging: d2d1d9c62c46dd2db49a952f7deb5b16ad2c9742
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
+ flutter_contacts: edb1c5ce76aa433e20e6cb14c615f4c0b66e0983
flutter_local_notifications: 4cde75091f6327eb8517fa068a0a5950212d2086
flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12
flutter_tts: 0f492aab6accf87059b72354fcb4ba934304771d
geolocator_apple: 6cbaf322953988e009e5ecb481f07efece75c450
- google_maps_flutter_ios: 5bc2be60ad012e79b182ce0fb0ef5030a50fb03e
+ Google-Maps-iOS-Utils: 66d6de12be1ce6d3742a54661e7a79cb317a9321
+ google_maps_flutter_ios: e31555a04d1986ab130f2b9f24b6cdc861acc6d3
google_sign_in_ios: 07375bfbf2620bc93a602c0e27160d6afc6ead38
- GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a
+ GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
GoogleMaps: 8939898920281c649150e0af74aa291c60f2e77d
GoogleSignIn: d4281ab6cf21542b1cfaff85c191f230b399d2db
- GoogleUtilities: ea963c370a38a8069cc5f7ba4ca849a60b6d7d15
+ GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
GTMAppAuth: f69bd07d68cd3b766125f7e072c45d7340dea0de
GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6
image_cropper: 37d40f62177c101ff4c164906d259ea2c3aa70cf
image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1
just_audio: baa7252489dbcf47a4c7cc9ca663e9661c99aafa
- local_auth_darwin: 4d56c90c2683319835a61274b57620df9c4520ab
+ local_auth_darwin: 66e40372f1c29f383a314c738c7446e2f7fdadc3
location: d5cf8598915965547c3f36761ae9cc4f4e87d22e
- nanopb: 438bc412db1928dac798aa6fd75726007be04262
+ nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
@@ -374,22 +394,22 @@ SPEC CHECKSUMS:
share: 0b2c3e82132f5888bccca3351c504d0003b3b410
sign_in_with_apple: f3bf75217ea4c2c8b91823f225d70230119b8440
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
- Stripe: 9fec845645e39f371e6898926d096fd9c2feb5a5
- stripe_ios: 03c617acee72e48a2d055d096a4b0ed2afebb256
- StripeApplePay: 5f017e8dfe259fafbab70137776189deef754bb2
- StripeCore: 01ec57f0dddfe742054dc6a322f811426c25313d
- StripeFinancialConnections: 56698cb6274bf89fb8c76b934f6156f368e97765
- StripePayments: 6adf11faf1b7038e77aa97019410305c6adca79d
- StripePaymentSheet: 3eaf870c4388e44b0cc37e4c69d00b6957fd8bd7
- StripePaymentsUI: 59ccddeacad592b09fa67e8d641340820ddb4751
- StripeUICore: 879bbf5889265db13f52fac8aad7a176ba62481f
+ Stripe: cdf416cf2efe286f532a6306de0fcaa0ecc8c71a
+ stripe_ios: 91946e5c07e0a0dc0e1484ee6659e1f90a302cf3
+ StripeApplePay: efb62ffc08e6cd4f161d77ddb45de2451075c54e
+ StripeCore: 9731f05e327c3dcaf7d7abd116840ceaa9482bbe
+ StripeFinancialConnections: 46c0049aaab3a179193502bce4a8096eb7b73f55
+ StripePayments: dd1867a620b0b8b5e294e9ff2f1f7b7770765f47
+ StripePaymentSheet: d155dfde74e90784d054deffb4f561a1f6dd638f
+ StripePaymentsUI: c24f990b03a68a7f6fe704b15dd487e7bb6b603e
+ StripeUICore: f2d514e900c37436dc5427fdf2c29d68ab1c2935
TOCropViewController: 80b8985ad794298fb69d3341de183f33d1853654
uni_links: d97da20c7701486ba192624d99bffaaffcfc298a
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
vibration: 7d883d141656a1c1a6d8d238616b2042a51a1241
video_player_avfoundation: 7c6c11d8470e1675df7397027218274b6d2360b3
wakelock_plus: 78ec7c5b202cab7761af8e2b2b3d0671be6c4ae1
- webview_flutter_wkwebview: 2a23822e9039b7b1bc52e5add778e5d89ad488d1
+ webview_flutter_wkwebview: 0982481e3d9c78fd5c6f62a002fcd24fc791f1e4
PODFILE CHECKSUM: d9271c147dd54ffd9ca5d77bf00ca21a1c9a5961
diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
index 0f46ccb..382ae34 100644
--- a/ios/Runner.xcodeproj/project.pbxproj
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -467,6 +467,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
@@ -594,6 +595,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
@@ -651,6 +653,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift
index 265f9be..3966f9f 100644
--- a/ios/Runner/AppDelegate.swift
+++ b/ios/Runner/AppDelegate.swift
@@ -4,7 +4,7 @@ import FirebaseCore
import GoogleMaps
// import Constants
-@UIApplicationMain
+@main
@objc class AppDelegate: FlutterAppDelegate {
override func application(
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index bbb234a..76cee0b 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -2,6 +2,10 @@
+ NSContactsUsageDescription
+ This app requires contacts access to function properly.
+ LSMinimumSystemVersion
+ 12.0
CFBundleURLTypes
@@ -37,11 +41,21 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
+<<<<<<< HEAD
51
CFBundleSignature
????
CFBundleVersion
4.3.51
+=======
+ 78
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 4.3.78
+ NSHumanReadableCopyright
+
+>>>>>>> 8813b4d
FirebaseAppDelegateProxyEnabled
NO
GMSApiKey
diff --git a/lib.zip b/lib.zip
new file mode 100644
index 0000000..0dd6247
Binary files /dev/null and b/lib.zip differ
diff --git a/lib/constant/api_key.dart b/lib/constant/api_key.dart
index 6433459..f0e2f77 100644
--- a/lib/constant/api_key.dart
+++ b/lib/constant/api_key.dart
@@ -51,6 +51,7 @@ class AK {
X.r(X.r(X.r(Env.payMobApikey, cn), cC), cs);
static final String integrationIdPayMobWallet =
X.r(X.r(X.r(Env.integrationIdPayMobWallet, cn), cC), cs);
+ static final String apiKeyHere = Env.apiKeyHere;
static final String smsPasswordEgypt =
X.r(X.r(X.r(Env.smsPasswordEgypt, cn), cC), cs);
static final String ocpApimSubscriptionKey = Env.ocpApimSubscriptionKey;
diff --git a/lib/constant/box_name.dart b/lib/constant/box_name.dart
index 63d9eb5..e2fbaa7 100644
--- a/lib/constant/box_name.dart
+++ b/lib/constant/box_name.dart
@@ -10,14 +10,21 @@ class BoxName {
static const String carType = "carType";
static const String carPlate = "carPlate";
static const String packagInfo = "packagInfo";
- static const String isVerified = '0';
+ static const String isVerified = 'isVerified';
+ static const String isFirstTime = 'isFirstTime';
+ static const String isSavedPhones = 'isSavedPhones';
static const String statusDriverLocation = "statusDriverLocation";
+ static const String isTest = "isTest";
static const String password = "password";
+ static const String validity = "validity";
+ static const String promo = "promo";
+ static const String discount = "discount";
static const String arrivalTime = "arrivalTime";
static const String passwordDriver = "passwordDriver";
static const String agreeTerms = "agreeTerms";
static const String addWork = 'addWork';
static const String addHome = 'addHome';
+ static const String placesDestination = 'placesDestination';
static const String tipPercentage = 'tipPercentage';
static const String accountIdStripeConnect = "accountIdStripeConnect";
static const String faceDetectTimes = "faceDetectTimes";
@@ -25,6 +32,11 @@ class BoxName {
static const String sosPhoneDriver = "sosPhoneDriver";
static const String passengerID = "pasengerID";
static const String phone = "phone";
+ static const String package = "package";
+ static const String isInstall = "isInstall";
+ static const String isGiftToken = "isGiftToken";
+ static const String inviteCode = "inviteCode";
+ static const String phoneWallet = "phoneWallet";
static const String phoneDriver = "phoneDriver";
static const String dobDriver = "dobDriver";
static const String sexDriver = "sexDriver";
@@ -68,7 +80,6 @@ class BoxName {
static const String vin = "vin";
static const String isvibrate = "isvibrate";
static const String make = "make";
- static const String hourWait = "hourWait";
static const String model = "model";
static const String year = "year";
static const String expirationDate = "expirationDate";
diff --git a/lib/constant/links.dart b/lib/constant/links.dart
index a661486..bb2c553 100644
--- a/lib/constant/links.dart
+++ b/lib/constant/links.dart
@@ -14,6 +14,8 @@ class AppLink {
// static final String server = Env.serverPHP;
static String googleMapsLink = 'https://maps.googleapis.com/maps/api/';
+ static String searcMaps =
+ 'https://autosuggest.search.hereapi.com/v1/autosuggest';
static String llama = 'https://api.llama-api.com/chat/completions';
static String gemini =
'https://generativelanguage.googleapis.com/v1beta3/models/text-bison-001:generateText';
@@ -51,16 +53,20 @@ class AppLink {
//=======================promo===================ride.mobile-app.store/ride/promo/get.php
static String promo = '$server/ride/promo';
static String getPassengersPromo = "$promo/get.php";
+ static String getPromoFirst = "$promo/getPromoFirst.php";
static String getPromoBytody = "$promo/getPromoBytody.php";
static String addPassengersPromo = "$promo/add.php";
static String deletePassengersPromo = "$promo/delete.php";
static String updatePassengersPromo = "$promo/update.php";
+ //===============contact==========================
+ static String savePhones = "$server/ride/egyptPhones/add.php";
+ static String getPhones = "$server/ride/egyptPhones/get.php";
+
////=======================cancelRide===================
static String ride = '$server/ride';
- static String addCancelRideFromPassenger =
- "$endPoint/ride/cancelRide/add.php";
- static String cancelRide = "$endPoint/ride/cancelRide/get.php";
+ static String addCancelRideFromPassenger = "$server/ride/cancelRide/add.php";
+ static String cancelRide = "$server/ride/cancelRide/get.php";
//-----------------ridessss------------------
static String addRides = "$ride/rides/add.php";
static String getRides = "$endPoint/ride/rides/get.php";
@@ -70,10 +76,10 @@ class AppLink {
"$endPoint/ride/rides/getRideStatusBegin.php";
static String getRideStatusFromStartApp =
"$ride/rides/getRideStatusFromStartApp.php";
- static String updateRides = "$endPoint/ride/rides/update.php";
+ static String updateRides = "$server/ride/rides/update.php";
static String updateStausFromSpeed =
- "$endPoint/ride/rides/updateStausFromSpeed.php";
- static String deleteRides = "$endPoint/ride/rides/delete.php";
+ "$server/ride/rides/updateStausFromSpeed.php";
+ static String deleteRides = "$server/ride/rides/delete.php";
//-----------------DriverPayment------------------
static String adddriverScam = "$ride/driver_scam/add.php";
@@ -105,13 +111,28 @@ class AppLink {
"$ride/notificationPassenger/update.php";
//-----------------Driver NotificationCaptain------------------
static String addNotificationCaptain = "$ride/notificationCaptain/add.php";
- static String addWaitingRide = "$ride/notificationCaptain/addWaitingRide.php";
- static String getRideWaiting = "$ride/notificationCaptain/getRideWaiting.php";
+ static String addWaitingRide =
+ "$server/ride/notificationCaptain/addWaitingRide.php";
+ static String updateWaitingTrip =
+ "$server/ride/notificationCaptain/updateWaitingTrip.php";
+ static String getRideWaiting =
+ "$endPoint/ride/notificationCaptain/getRideWaiting.php";
static String getNotificationCaptain = "$ride/notificationCaptain/get.php";
static String updateNotificationCaptain =
"$ride/notificationCaptain/update.php";
static String deleteNotificationCaptain =
"$ride/notificationCaptain/delete.php";
+ //-----------------invitor------------------
+
+ static String addInviteDriver = "$server/ride/invitor/add.php";
+ static String addInvitationPassenger =
+ "$server/ride/invitor/addInvitationPassenger.php";
+ static String getInviteDriver = "$server/ride/invitor/get.php";
+ static String getDriverInvitationToPassengers =
+ "$server/ride/invitor/getDriverInvitationToPassengers.php";
+ static String updateInviteDriver = "$server/ride/invitor/update.php";
+ static String updatePassengerGift =
+ "$server/ride/invitor/updatePassengerGift.php";
//-----------------Api Key------------------
static String addApiKey = "$ride/apiKey/add.php";
static String getApiKey = "$ride/apiKey/get.php";
@@ -121,6 +142,7 @@ class AppLink {
//-----------------Feed Back------------------
static String addFeedBack = "$ride/feedBack/add.php";
+ static String uploadAudio = "$ride/feedBack/upload_audio.php";
static String getFeedBack = "$ride/feedBack/get.php";
static String updateFeedBack = "$ride/feedBack/updateFeedBack.php";
@@ -142,7 +164,8 @@ class AppLink {
static String updateLicense = "$ride/license/updateFeedBack.php";
//-----------------RegisrationCar------------------
static String addRegisrationCar = "$ride/RegisrationCar/add.php";
- static String getRegisrationCar = "$endPoint/ride/RegisrationCar/get.php";
+ static String getRegisrationCar =
+ "${box.read(BoxName.serverChosen)}/ride/RegisrationCar/get.php";
static String selectDriverAndCarForMishwariTrip =
"$ride/RegisrationCar/selectDriverAndCarForMishwariTrip.php";
static String updateRegisrationCar = "$ride/RegisrationCar/update.php";
@@ -150,6 +173,7 @@ class AppLink {
//-----------------mishwari------------------
static String addMishwari = "$ride/mishwari/add.php";
+ static String cancelMishwari = "$ride/mishwari/cancel.php";
static String getMishwari = "$ride/mishwari/get.php";
//-----------------DriverOrder------------------
@@ -163,6 +187,8 @@ class AppLink {
// =====================================
static String addRateToPassenger = "$ride/rate/add.php";
+ static String savePlacesServer = "$ride/places/add.php";
+ static String getapiKey = "$ride/apiKey/get.php";
static String addRateToDriver = "$ride/rate/addRateToDriver.php";
static String getDriverRate = "$ride/rate/getDriverRate.php";
static String getPassengerRate = "$ride/rate/getPassengerRate.php";
@@ -183,12 +209,14 @@ class AppLink {
static String uploadEgypt = "$server/uploadEgypt.php";
//==================certifcate==========
- static String location = '$endPoint/ride/location';
+ static String location = '${box.read(BoxName.serverChosen)}/ride/location';
static String getCarsLocationByPassenger = "$location/get.php";
static String addpassengerLocation = "$location/addpassengerLocation.php";
static String getCarsLocationByPassengerSpeed = "$location/getSpeed.php";
static String getCarsLocationByPassengerComfort = "$location/getComfort.php";
static String getCarsLocationByPassengerBalash = "$location/getBalash.php";
+ static String getCarsLocationByPassengerPinkBike =
+ "$location/getPinkBike.php";
static String getCarsLocationByPassengerDelivery =
"$location/getDelivery.php";
static String getLocationParents = "$location/getLocationParents.php";
@@ -239,7 +267,10 @@ class AppLink {
static String deletecaptainAccounr = "$authCaptin/deletecaptainAccounr.php";
static String updateAccountBank = "$authCaptin/updateAccountBank.php";
static String getAccount = "$authCaptin/getAccount.php";
-
+ static String updatePassengersInvitation =
+ "$server/ride/invitor/updatePassengersInvitation.php";
+ static String updateDriverInvitationDirectly =
+ "$server/ride/invitor/updateDriverInvitationDirectly.php";
//===================Admin Captin============
static String getPassengerDetailsByPassengerID =
@@ -248,6 +279,7 @@ class AppLink {
static String getPassengerbyEmail = "$server/Admin/getPassengerbyEmail.php";
static String addAdminUser = "$server/Admin/adminUser/add.php";
static String getAdminUser = "$server/Admin/adminUser/get.php";
+ static String addError = "$server/Admin/errorApp.php";
static String getCaptainDetailsByEmailOrIDOrPhone =
"$server/Admin/AdminCaptain/getCaptainDetailsByEmailOrIDOrPhone.php";
static String getCaptainDetails = "$server/Admin/AdminCaptain/get.php";
diff --git a/lib/constant/notification.dart b/lib/constant/notification.dart
new file mode 100644
index 0000000..7ede7a2
--- /dev/null
+++ b/lib/constant/notification.dart
@@ -0,0 +1,22 @@
+List messages = [
+ "🚗 عروض مميزة: استمتع بأقل الأسعار وأفضل العروض! افتح تطبيق سفر الآن لتحصل على المزيد من الخيارات. 🌟",
+ "💸 وفر الآن: وفر مع تطبيق سفر! عروض مستمرة وخيارات متعددة تناسب احتياجاتك. 🔥",
+ "🔒 أمان وراحة: مع تطبيق سفر، احصل على أمان وراحة بأفضل الأسعار! 🚕",
+ "💼 خيارات متنوعة: استفد من خيارات متنوعة وأسعار تنافسية على تطبيق سفر، الأفضل دائماً. 🌐",
+ "💵 توفير مضمون: حافظ على ميزانيتك وسافر بأمان مع تطبيق سفر – العروض لا تتوقف! 🎉",
+ "🌍 وجهات مميزة: أفضل وجهات السفر، بأقل الأسعار مع تطبيق سفر – تابعنا الآن! 🛤️",
+ "🛣️ سهولة وراحة: رحلاتك أصبحت أسهل وأرخص – سافر معنا وتمتع بأفضل التجارب. 🎊",
+ "📲 حجز سهل: احجز رحلتك بسهولة وأمان مع سفر – المزيد من الخصومات في انتظارك! 🎁",
+ "👑 فئة مميزة: خليك من الفئة المميزة واستفد بأفضل الأسعار مع تطبيق سفر. 💯",
+ "💡 خيارات متعددة: نوفر لك خيارات متعددة وسعر مناسب – جرب تطبيق سفر الآن! 🚖",
+ "✨ عروض متجددة: العروض لا تتوقف على تطبيق سفر – احجز رحلتك الآن وتمتع بالمزيد! 📅",
+ "🚀 سهولة الوصول: السفر أصبح أسهل وأسرع مع تطبيق سفر – كن مستعدًا لأفضل التجارب! 🌠",
+ "🧳 راحة وأمان: تطبيق سفر يقدم لك أمان وراحة بأقل الأسعار! 📉",
+ "🔥 عروض فورية: احجز الآن واستمتع بعروض لا تُفوّت على تطبيق سفر! 🚘",
+ "🚖 أسعار تنافسية: اختر رحلتك الآن بأسعار تنافسية وتمتع بالراحة والأمان مع تطبيق سفر. ✅",
+ "💥 أسعار خاصة: أسعار خاصة بانتظارك على تطبيق سفر! افتح التطبيق الآن واحجز رحلتك. 🌐",
+ "🌟 راحة البال: انطلق بأمان وراحة مع تطبيق سفر – استمتع بأفضل الأسعار. 💸",
+ "📍 خصومات حصرية: استفد من الخصومات الحصرية والعروض المستمرة على تطبيق سفر! 🛤️",
+ "🛫 تجربة سهلة: رحلاتك أصبحت أفضل وأسهل مع تطبيق سفر – افتح التطبيق واستمتع بالتجربة. ✨",
+ "🔔 عروض لا مثيل لها: كن جاهزًا لعروض لا مثيل لها! تطبيق سفر يقدم لك أفضل الخيارات بأقل الأسعار. 🎉",
+];
diff --git a/lib/constant/style.dart b/lib/constant/style.dart
index 9d13b27..a0993aa 100644
--- a/lib/constant/style.dart
+++ b/lib/constant/style.dart
@@ -5,35 +5,39 @@ import 'package:google_fonts/google_fonts.dart';
import 'colors.dart';
class AppStyle {
- static TextStyle headTitle = TextStyle(
- fontWeight: FontWeight.bold,
- fontSize: 40,
- color: AppColor.accentColor,
- fontFamily: box.read(BoxName.lang) == 'ar'
- // ?GoogleFonts.notoNaskhArabic().fontFamily
- ? GoogleFonts.notoNaskhArabic().fontFamily
- : GoogleFonts.roboto().fontFamily);
- static TextStyle headTitle2 = TextStyle(
- fontWeight: FontWeight.bold,
- fontSize: 26,
- color: AppColor.writeColor,
- fontFamily: box.read(BoxName.lang) == 'ar'
- ? GoogleFonts.notoNaskhArabic().fontFamily
- : GoogleFonts.roboto().fontFamily);
+ static TextStyle headTitle = const TextStyle(
+ fontWeight: FontWeight.bold,
+ fontSize: 40,
+ color: AppColor.accentColor,
+ // fontFamily: box.read(BoxName.lang) == 'ar'
+ // // ?GoogleFonts.notoNaskhArabic().fontFamily
+ // ? GoogleFonts.notoNaskhArabic().fontFamily
+ // : GoogleFonts.roboto().fontFamily,
+ );
+ static TextStyle headTitle2 = const TextStyle(
+ fontWeight: FontWeight.bold,
+ fontSize: 22,
+ color: AppColor.writeColor,
+ // fontFamily: box.read(BoxName.lang) == 'ar'
+ // ? GoogleFonts.notoNaskhArabic().fontFamily
+ // : GoogleFonts.roboto().fontFamily
+ );
static TextStyle title = TextStyle(
- fontWeight: FontWeight.normal,
- fontSize: box.read(BoxName.lang) == 'ar' ? 14 : 16,
- color: AppColor.writeColor,
- fontFamily: box.read(BoxName.lang) == 'ar'
- ? GoogleFonts.notoNaskhArabic().fontFamily
- : GoogleFonts.roboto().fontFamily);
- static TextStyle subtitle = TextStyle(
- fontWeight: FontWeight.bold,
- fontSize: 13,
- color: AppColor.writeColor,
- fontFamily: box.read(BoxName.lang) == 'ar'
- ? GoogleFonts.notoNaskhArabic().fontFamily
- : GoogleFonts.roboto().fontFamily);
+ fontWeight: FontWeight.normal,
+ fontSize: box.read(BoxName.lang) == 'ar' ? 14 : 16,
+ color: AppColor.writeColor,
+ // fontFamily: box.read(BoxName.lang) == 'ar'
+ // ? GoogleFonts.notoNaskhArabic().fontFamily
+ // : GoogleFonts.roboto().fontFamily
+ );
+ static TextStyle subtitle = const TextStyle(
+ fontWeight: FontWeight.bold,
+ fontSize: 13,
+ color: AppColor.writeColor,
+ // fontFamily: box.read(BoxName.lang) == 'ar'
+ // ? GoogleFonts.notoNaskhArabic().fontFamily
+ // : GoogleFonts.roboto().fontFamily
+ );
static TextStyle number = const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14,
@@ -43,7 +47,9 @@ class AppStyle {
static BoxDecoration boxDecoration = const BoxDecoration(
boxShadow: [
BoxShadow(
- color: AppColor.accentColor, blurRadius: 5, offset: Offset(2, 4)),
+ color: Color.fromARGB(255, 218, 218, 255),
+ blurRadius: 5,
+ offset: Offset(2, 4)),
BoxShadow(
color: AppColor.accentColor, blurRadius: 5, offset: Offset(-2, -2))
],
diff --git a/lib/constant/univeries_polygon.dart b/lib/constant/univeries_polygon.dart
new file mode 100644
index 0000000..8358b9f
--- /dev/null
+++ b/lib/constant/univeries_polygon.dart
@@ -0,0 +1,83 @@
+import 'package:google_maps_flutter/google_maps_flutter.dart';
+
+class UniversitiesPolygons {
+ // AUC polygon points
+ static const List> universityPolygons = [
+ // AUC Polygon
+ [
+ LatLng(30.013431, 31.502572),
+ LatLng(30.018469, 31.497478),
+ LatLng(30.023158, 31.495870),
+ LatLng(30.025084, 31.496781),
+ LatLng(30.018701, 31.511393),
+ LatLng(30.015312, 31.508310),
+ ],
+ // Example polygon for University 'German University in Cairo (GUC)'
+ [
+ LatLng(29.984554, 31.437829),
+ LatLng(29.990363, 31.438390),
+ LatLng(29.990560, 31.445643),
+ LatLng(29.984436, 31.445825),
+ ],
+ //Future University in Egypt (FUE)
+ [
+ LatLng(30.025794, 31.490946),
+ LatLng(30.028341, 31.491014),
+ LatLng(30.028341, 31.492586),
+ LatLng(30.025844, 31.492491),
+ ],
+ //'British University in Egypt (BUE)'
+ [
+ LatLng(30.117423, 31.605834),
+ LatLng(30.118224, 31.605543),
+ LatLng(30.118649, 31.607361),
+ LatLng(30.118932, 31.608033),
+ LatLng(30.119592, 31.612159),
+ LatLng(30.119372, 31.612958),
+ LatLng(30.120017, 31.617102),
+ LatLng(30.119435, 31.617193),
+ ],
+ //Misr International University (MIU)
+ [
+ LatLng(30.166498, 31.491663),
+ LatLng(30.171956, 31.491060),
+ LatLng(30.172212, 31.495754),
+ LatLng(30.167112, 31.496108),
+ ],
+ // Canadian International College (CIC)
+ [
+ LatLng(30.034312, 31.428963),
+ LatLng(30.035661, 31.429037),
+ LatLng(30.036074, 31.430522),
+ LatLng(30.036017, 31.431146),
+ LatLng(30.034580, 31.431117),
+ ],
+ // October 6 University (O6U)
+ [
+ LatLng(29.974102, 30.946934),
+ LatLng(29.976620, 30.944925),
+ LatLng(29.979848, 30.949832),
+ LatLng(29.977372, 30.951950),
+ ],
+ [
+ LatLng(30.029312, 31.210046),
+ LatLng(30.027124, 31.201393),
+ LatLng(30.014523, 31.205087),
+ LatLng(30.015416, 31.212218),
+ LatLng(30.027325, 31.210661),
+ ],
+ // Add polygons for 8 more universities...
+ ];
+
+ static const List universityNames = [
+ "American University in Cairo (AUC)",
+ 'German University in Cairo (GUC)',
+ 'Future University in Egypt (FUE)',
+ 'British University in Egypt (BUE)',
+ 'Misr International University (MIU)',
+ 'Canadian International College (CIC)',
+ 'October 6 University (O6U)',
+ "Cairo University",
+ // Add names for 8 more universities...
+ ];
+}
diff --git a/lib/controller/auth/google_sign.dart b/lib/controller/auth/google_sign.dart
index b46f940..f02d2e6 100644
--- a/lib/controller/auth/google_sign.dart
+++ b/lib/controller/auth/google_sign.dart
@@ -1,10 +1,17 @@
+import 'dart:io';
+
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/controller/auth/login_controller.dart';
import 'package:SEFER/main.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:google_sign_in/google_sign_in.dart';
+import 'package:url_launcher/url_launcher.dart';
+import '../../constant/links.dart';
import '../../onbording_page.dart';
+import '../functions/crud.dart';
class GoogleSignInHelper {
static final GoogleSignIn _googleSignIn = GoogleSignIn(
@@ -32,26 +39,114 @@ class GoogleSignInHelper {
}
}
- static Future signInFromLogin() async {
+ Future signInFromLogin() async {
try {
final GoogleSignInAccount? googleUser = await _googleSignIn.signIn();
if (googleUser != null) {
await _handleSignUp(googleUser);
- // if (box.read(BoxName.countryCode) == 'Egypt') {
await Get.put(LoginController()).loginUsingCredentials(
box.read(BoxName.passengerID).toString(),
box.read(BoxName.email).toString(),
);
- // } else if (box.read(BoxName.countryCode) == 'Jordan') {
- // // Get.to(() => AiPage());
- // }
}
return googleUser;
} catch (error) {
+ // if (error is GoogleSignInAuthenticationException) {
+ // // Handle authentication errors from Google Sign-In
+ // addError("Google sign-in authentication error: ${error.message}",
+ // ' signInFromLogin()');
+ // } else if (error is GoogleSignInAccountNotFoundException) {
+ // // Handle the case where the user is not found (if applicable)
+ // addError("Google sign-in account not found error: ${error.message}",
+ // ' signInFromLogin()');
+ // }
+ // else
+ if (error is SocketException) {
+ // Handle network issues, like SSL certificate issues
+ addError("Network error (SSL certificate issue): ${error.message}",
+ ' signInFromLogin()');
+ } else if (error is PlatformException) {
+ // Handle platform-specific errors, like Google Play Services issues
+ if (error.code == 'sign_in_required') {
+ // Google Play Services are required but not installed or outdated
+ showGooglePlayServicesError();
+ } else {
+ addError("Platform error: ${error.message}",
+ ' signInFromLogin()');
+ }
+ } else {
+ // Catch all other unknown errors
+ addError("Unknown error: ${error.toString()}",
+ ' signInFromLogin()');
+ }
return null;
}
}
+ void showGooglePlayServicesError() async {
+ const playStoreUrl =
+ 'https://play.google.com/store/apps/details?id=com.google.android.gms&hl=en_US';
+
+ if (await canLaunchUrl(Uri.parse(playStoreUrl))) {
+ await launchUrl(Uri.parse(playStoreUrl));
+ } else {
+ // Fallback if the URL can't be opened
+ showDialog(
+ context: Get.context!,
+ builder: (BuildContext context) {
+ return AlertDialog(
+ title: Text('Error'.tr),
+ content: Text(
+ 'Could not open the Google Play Store. Please update Google Play Services manually.'
+ .tr),
+ actions: [
+ TextButton(
+ onPressed: () => Navigator.pop(context),
+ child: Text('Close'.tr),
+ ),
+ ],
+ );
+ },
+ );
+ }
+ }
+
+ // Future signInFromLogin() async {
+ // try {
+ // final GoogleSignInAccount? googleUser = await _googleSignIn.signIn();
+ // if (googleUser != null) {
+ // await _handleSignUp(googleUser);
+ // // if (box.read(BoxName.countryCode) == 'Egypt') {
+ // await Get.put(LoginController()).loginUsingCredentials(
+ // box.read(BoxName.passengerID).toString(),
+ // box.read(BoxName.email).toString(),
+ // );
+ // // } else if (box.read(BoxName.countryCode) == 'Jordan') {
+ // // // Get.to(() => AiPage());
+ // // }
+ // }
+ // return googleUser;
+ // } catch (error) {
+ // addError(error.toString(), ' signInFromLogin()');
+ // return null;
+ // }
+ // }
+
+ addError(String error, where) async {
+ CRUD().post(link: AppLink.addError, payload: {
+ 'error': error.toString(), // Example error description
+ 'userId': box.read(BoxName.driverID) ??
+ box.read(BoxName.passengerID), // Example user ID
+ 'userType': box.read(BoxName.driverID) != null
+ ? 'Driver'
+ : 'passenger', // Example user type
+ 'phone': box.read(BoxName.phone) ??
+ box.read(BoxName.phoneDriver), // Example phone number
+
+ 'device': where
+ });
+ }
+
// Method to handle Google Sign-Out
static Future signOut() async {
try {
diff --git a/lib/controller/auth/login_controller.dart b/lib/controller/auth/login_controller.dart
index bef43cf..d2f4745 100644
--- a/lib/controller/auth/login_controller.dart
+++ b/lib/controller/auth/login_controller.dart
@@ -1,9 +1,12 @@
import 'dart:convert';
+import 'dart:io';
import 'package:SEFER/constant/info.dart';
import 'package:SEFER/controller/firebase/firbase_messge.dart';
+import 'package:SEFER/controller/functions/add_error.dart';
import 'package:SEFER/views/auth/login_page.dart';
import 'package:SEFER/views/auth/sms_verfy_page.dart';
+import 'package:SEFER/views/widgets/my_dialog.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:SEFER/constant/box_name.dart';
@@ -13,6 +16,9 @@ import 'package:SEFER/main.dart';
import 'package:SEFER/views/home/map_page_passenger.dart';
import 'package:location/location.dart';
+import '../../print.dart';
+import '../functions/package_info.dart';
+
class LoginController extends GetxController {
final formKey = GlobalKey();
final formKeyAdmin = GlobalKey();
@@ -29,9 +35,20 @@ class LoginController extends GetxController {
update();
}
- getAppTester(String appPlatform) async {
- var res = await CRUD()
- .get(link: AppLink.getTesterApp, payload: {'appPlatform': appPlatform});
+ @override
+ void onInit() async {
+ box.read(BoxName.isTest) == null ||
+ box.read(BoxName.isTest).toString() == '0'
+ ? await getAppTester()
+ : null;
+
+ super.onInit();
+ }
+
+ getAppTester() async {
+ var res = await CRUD().get(
+ link: AppLink.getTesterApp,
+ payload: {'appPlatform': AppInformation.appName});
if (res != 'failure') {
var d = jsonDecode(res);
@@ -64,6 +81,8 @@ class LoginController extends GetxController {
await CRUD().get(link: AppLink.loginFromGooglePassenger, payload: {
'email': email,
'id': passengerID,
+ "platform": Platform.isAndroid ? 'android' : 'ios',
+ "appName": AppInformation.appName,
});
if (res == 'Failure') {
Get.offAll(SmsSignupEgypt());
@@ -73,12 +92,22 @@ class LoginController extends GetxController {
} else {
var jsonDecoeded = jsonDecode(res);
if (jsonDecoeded.isNotEmpty) {
+ var d = jsonDecoeded['data'][0];
if (jsonDecoeded['status'] == 'success' &&
- jsonDecoeded['data'][0]['verified'].toString() == '1') {
+ d['verified'].toString() == '1') {
//
+
box.write(BoxName.isVerified, '1');
- box.write(BoxName.email, jsonDecoeded['data'][0]['email']);
- box.write(BoxName.phone, jsonDecoeded['data'][0]['phone']);
+ box.write(BoxName.email, d['email']);
+ box.write(BoxName.phone, d['phone']);
+ box.write(BoxName.isTest, '1');
+ box.write(BoxName.package, d['package']);
+ box.write(BoxName.promo, d['promo']);
+ box.write(BoxName.discount, d['discount']);
+ box.write(BoxName.validity, d['validity']);
+ box.write(BoxName.isInstall, d['isInstall'] ?? 'none');
+ box.write(BoxName.isGiftToken, d['isGiftToken'] ?? 'none');
+ box.write(BoxName.inviteCode, d['inviteCode'] ?? 'none');
var token = await CRUD().get(link: AppLink.getTokens, payload: {
'passengerID': box.read(BoxName.passengerID).toString()
@@ -86,34 +115,85 @@ class LoginController extends GetxController {
if (token != 'failure') {
if (jsonDecode(token)['data'][0]['token'] !=
box.read(BoxName.tokenFCM)) {
- Get.put(FirebaseMessagesController())
- .sendNotificationToAnyWithoutData(
+ Get.put(FirebaseMessagesController()).sendNotificationToDriverMAP(
'token change'.tr,
'change device'.tr,
jsonDecode(token)['data'][0]['token'].toString(),
+ [],
'cancel.wav',
);
Future.delayed(const Duration(seconds: 1));
- await CRUD().post(link: AppLink.addTokens, payload: {
- 'token': box.read(BoxName.tokenFCM),
- 'passengerID': box.read(BoxName.passengerID).toString()
- });
- // Get.defaultDialog(
- // title: 'Device Change Detected'.tr,
- // middleText:
- // 'You can only use one device at a time. This device will now be set as your active device.'
- // .tr,
- // textConfirm: 'OK'.tr,
- // confirmTextColor: Colors.white,
- // onConfirm: () {
- // Get.back();
- // Get.offAll(() => const MapPagePassenger());
- // },
- // );
- // Get.snackbar('title', 'message');
+ await CRUD().post(
+ link: "${AppLink.server}/ride/firebase/add.php",
+ payload: {
+ 'token': box.read(BoxName.tokenFCM),
+ 'passengerID': box.read(BoxName.passengerID).toString()
+ });
+ CRUD().post(
+ link:
+ "${AppLink.seferAlexandriaServer}/ride/firebase/add.php",
+ payload: {
+ 'token': box.read(BoxName.tokenFCM),
+ 'passengerID': box.read(BoxName.passengerID).toString()
+ });
+ CRUD().post(
+ link: "${AppLink.seferGizaServer}/ride/firebase/add.php",
+ payload: {
+ 'token': box.read(BoxName.tokenFCM),
+ 'passengerID': box.read(BoxName.passengerID).toString()
+ });
+ Get.defaultDialog(
+ title: 'Device Change Detected'.tr,
+ middleText:
+ 'You can only use one device at a time. This device will now be set as your active device.'
+ .tr,
+ textConfirm: 'OK'.tr,
+ confirmTextColor: Colors.white,
+ onConfirm: () {
+ Get.back();
+ Get.offAll(() => const MapPagePassenger());
+ },
+ );
+ } else {
+ print('same');
}
+ } // Logging to check if inviteCode is written correctly
+
+ if (box.read(BoxName.inviteCode).toString() != 'none' &&
+ box.read(BoxName.isInstall).toString() != '1') {
+ await CRUD()
+ .post(link: AppLink.updatePassengersInvitation, payload: {
+ "inviteCode": box.read(BoxName.inviteCode).toString(),
+ "passengerID": box.read(BoxName.passengerID).toString(),
+ });
+ Get.defaultDialog(
+ title: 'Invitation Used'
+ .tr, // Automatically translates based on the current locale
+ middleText: "Your invite code was successfully applied!"
+ .tr, // Automatically translates based on the current locale
+ onConfirm: () {
+ try {
+ CRUD().post(link: AppLink.addPassengersPromo, payload: {
+ "promoCode":
+ 'S-${box.read(BoxName.name).toString().split(' ')[0]}',
+ "amount": '25',
+ "passengerID": box.read(BoxName.passengerID).toString(),
+ "description": 'promo first'
+ });
+ } catch (e) {
+ addError(e.toString(),
+ 'passenger Invitation Used dialogu as promo line 185 login_controller');
+ } finally {
+ // Continue with the rest of your flow, regardless of errors
+ // For example, navigate to the next page
+ Get.offAll(() => const MapPagePassenger());
+ }
+ },
+ textConfirm: "OK".tr, // Confirm button text
+ );
+ } else {
+ Get.offAll(() => const MapPagePassenger());
}
- Get.offAll(() => const MapPagePassenger());
} else {
Get.offAll(() => SmsSignupEgypt());
// Get.snackbar(jsonDecoeded['status'], jsonDecoeded['data'],
@@ -128,34 +208,6 @@ class LoginController extends GetxController {
}
}
- // void adminDashboardOpen() async {
- // if (formKeyAdmin.currentState!.validate()) {
- // await DeviceInfoPlus.getDeviceInfo();
- // if (Platform.isAndroid) {
- // // var res = await CRUD().get(link: AppLink.getAdminUser, payload: {
- // // // 'device_number': DeviceInfoPlus.deviceData['serialNumber'].toString(),
- // // });
- // // var d = jsonDecode(res);
- // // // if (DeviceInfoPlus.deviceData['serialNumber'] ==
- // // d['message']['device_number']) {
- // Get.back();
- // Get.to(() => const AdminHomePage());
- // // }
- // }
- // if (Platform.isIOS) {
- // // var res = await CRUD().get(link: AppLink.getAdminUser, payload: {
- // // 'device_number': DeviceInfoPlus.deviceData['identifierForVendor'].toString(),
- // // });
- // // var d = jsonDecode(res);
- // // if (DeviceInfoPlus.deviceData['serialNumber'] ==
- // // d['message']['device_number']) {
- // Get.back();
- // Get.to(() => const AdminHomePage());
- // // }
- // }
- // }
- // }
-
void login() async {
isloading = true;
update();
@@ -204,6 +256,12 @@ class LoginController extends GetxController {
}
}
+ goToMapPage() {
+ if (box.read(BoxName.email) != null) {
+ Get.offAll(() => const MapPagePassenger());
+ }
+ }
+
final location = Location();
// late PermissionStatus permissionGranted = PermissionStatus.denied;
@@ -236,15 +294,4 @@ class LoginController extends GetxController {
}
update();
}
-
- @override
- void onInit() async {
- // permissionLocation = await Permission.locationWhenInUse.isGranted;
- await getAppTester(AppInformation.appName);
- // if (isTest == 0 && box.read(BoxName.passengerID) != null) {
- // // await loginUsingCredentials(
- // // box.read(BoxName.passengerID), box.read(BoxName.email));
- // }
- super.onInit();
- }
}
diff --git a/lib/controller/auth/onboarding_controller.dart b/lib/controller/auth/onboarding_controller.dart
index 1edc952..2746e84 100644
--- a/lib/controller/auth/onboarding_controller.dart
+++ b/lib/controller/auth/onboarding_controller.dart
@@ -22,7 +22,7 @@ class OnBoardingControllerImp extends OnBoardingController {
if (currentPage > onBoardingList.length - 1) {
box.write(BoxName.onBoarding, 'yes');
- Get.offAll(LoginPage());
+ Get.offAll(() => LoginPage());
} else {
pageController.animateToPage(currentPage,
duration: const Duration(milliseconds: 900), curve: Curves.easeInOut);
diff --git a/lib/controller/auth/register_controller.dart b/lib/controller/auth/register_controller.dart
index 6edfad7..d01ceee 100644
--- a/lib/controller/auth/register_controller.dart
+++ b/lib/controller/auth/register_controller.dart
@@ -3,7 +3,11 @@ import 'dart:convert';
import 'dart:math';
import 'package:SEFER/constant/colors.dart';
+import 'package:SEFER/controller/auth/login_controller.dart';
+import 'package:SEFER/controller/functions/add_error.dart';
+import 'package:SEFER/controller/local/phone_intel/phone_number.dart';
import 'package:SEFER/views/home/map_page_passenger.dart';
+import 'package:SEFER/views/widgets/my_dialog.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:SEFER/constant/links.dart';
@@ -14,14 +18,14 @@ import 'package:SEFER/views/widgets/elevated_btn.dart';
import '../../constant/box_name.dart';
import '../../main.dart';
+import '../../print.dart';
import '../../views/auth/verify_email_page.dart';
import '../functions/sms_controller.dart';
class RegisterController extends GetxController {
final formKey = GlobalKey();
final formKey3 = GlobalKey();
- List countryCodes = ['+1', '+91', '+44'];
- String selectedCountryCode = '+1';
+
TextEditingController firstNameController = TextEditingController();
TextEditingController lastNameController = TextEditingController();
TextEditingController emailController = TextEditingController();
@@ -41,11 +45,6 @@ class RegisterController extends GetxController {
super.onInit();
}
- void updateCountryCode(String newCode) {
- selectedCountryCode = newCode;
- update();
- }
-
void startTimer() {
_timer?.cancel(); // Cancel any existing timer
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
@@ -119,166 +118,207 @@ class RegisterController extends GetxController {
}
sendOtpMessage() async {
- SmsEgyptController smsEgyptController = Get.put(SmsEgyptController());
-
- int randomNumber = Random().nextInt(100000) + 1;
+ SmsEgyptController smsEgyptController;
isLoading = true;
update();
- if (formKey3.currentState!.validate()) {
- if (box.read(BoxName.countryCode) == 'Egypt') {
- if (isValidEgyptianPhoneNumber(phoneController.text) == true) {
- var responseCheker = await CRUD()
- .post(link: AppLink.checkPhoneNumberISVerfiedPassenger, payload: {
- 'phone_number': '+2${phoneController.text}',
- 'email': box.read(BoxName.email),
- });
- if (responseCheker != 'failure') {
- var d = jsonDecode(responseCheker);
- if (d['message'][0]['verified'].toString() == '1') {
+ try {
+ // Initialize SmsEgyptController
+ smsEgyptController = Get.put(SmsEgyptController());
+
+ // Generate a random OTP
+ int randomNumber = Random().nextInt(100000) + 1;
+
+ isLoading = true;
+ update();
+
+ // Get phone number from controller
+ String phoneNumber = phoneController.text;
+
+ // Check if the phone number is from Egypt (Assuming Egyptian numbers start with +20)
+
+ if (phoneController.text.isNotEmpty) {
+ bool isEgyptianNumber = phoneNumber.startsWith('+20');
+ if (isEgyptianNumber && phoneNumber.length == 13) {
+ // Check if the phone number is already verified
+ var responseChecker = await CRUD().post(
+ link: AppLink.checkPhoneNumberISVerfiedPassenger,
+ payload: {
+ 'phone_number': phoneNumber,
+ 'email': box.read(BoxName.email),
+ },
+ );
+
+ if (responseChecker != 'failure') {
+ var data = jsonDecode(responseChecker);
+
+ // If the phone number is already verified
+ if (data['message'][0]['verified'].toString() == '1') {
Get.snackbar('Phone number is verified before'.tr, '',
backgroundColor: AppColor.greenColor);
box.write(BoxName.isVerified, '1');
- box.write(BoxName.phone, '+2${phoneController.text}');
+ box.write(BoxName.phone, phoneNumber);
Get.offAll(const MapPagePassenger());
} else {
- await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: {
- 'phone_number': '+2${phoneController.text}',
- 'token': randomNumber.toString(),
- });
-
- await smsEgyptController.sendSmsEgypt(
- phoneController.text.toString(), randomNumber.toString());
- isSent = true;
- remainingTime = 300; // Reset to 5 minutes
- startTimer();
- isLoading = false;
- update();
+ await sendOtp(phoneNumber, randomNumber, isEgyptianNumber,
+ smsEgyptController);
}
} else {
- await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: {
- 'phone_number': '+2${phoneController.text}',
- 'token': randomNumber.toString(),
- });
-
- await smsEgyptController.sendSmsEgypt(
- phoneController.text.toString(), randomNumber.toString());
- isSent = true;
- remainingTime = 300; // Reset to 5 minutes
- startTimer();
- isLoading = false;
- update();
-
- // Get.snackbar(responseCheker, 'message');
+ await sendOtp(phoneNumber, randomNumber, isEgyptianNumber,
+ smsEgyptController);
}
- } else if (isValidPhoneNumber(phoneController.text)) {
- await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: {
- 'phone_number': '+${phoneController.text}',
- 'token': randomNumber.toString(),
- });
- await smsEgyptController.sendWhatsAppAuth(
- phoneController.text, randomNumber.toString());
- // await smsEgyptController.sendSmsEgypt(
- // phoneController.text.toString(), randomNumber.toString());
- isSent = true;
- remainingTime = 300; // Reset to 5 minutes
- startTimer();
- isLoading = false;
- update();
- } else {
- Get.snackbar('Phone Number wrong'.tr, '',
- backgroundColor: AppColor.redColor,
- duration: const Duration(seconds: 5));
+ } else if (phoneNumber.length > 9) {
+ sendOtp(
+ phoneNumber, randomNumber, isEgyptianNumber, smsEgyptController);
}
+ } else {
+ MyDialog().getDialog(
+ 'Error'.tr, 'Phone number must be exactly 11 digits long'.tr, () {
+ Get.back();
+ });
+ // sendOtp(
+ // phoneNumber, randomNumber, isEgyptianNumber, smsEgyptController);
}
+ } catch (e) {
+ // Handle error
+ } finally {
+ isLoading = false;
+ update();
}
}
- verifySMSCode() async {
- // if (formKey3.currentState!.validate()) {
- if (isValidEgyptianPhoneNumber(phoneController.text)) {
- var res = await CRUD().post(link: AppLink.verifyOtpMessage, payload: {
- 'phone_number': '+2${phoneController.text}',
- 'token': verifyCode.text.toString(),
+// Helper function to send OTP or WhatsApp message based on phone number location
+ Future sendOtp(String phoneNumber, int otp, bool isEgyptian,
+ SmsEgyptController controller) async {
+ // Trim any leading or trailing whitespace from the phone number
+ phoneNumber = phoneNumber.trim();
+ var dd = await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: {
+ 'phone_number': phoneNumber,
+ 'token': otp.toString(),
+ });
+ Log.print('dd: ${dd}');
+ if (isEgyptian) {
+ await CRUD().post(link: AppLink.updatePhoneInvalidSMSPassenger, payload: {
+ "phone_number": Get.find().phoneController.text
});
- if (res != 'failure') {
- // var dec = jsonDecode(res);
- box.write(BoxName.phoneDriver, '+2${phoneController.text}');
- var payload = {
- 'id': box.read(BoxName.passengerID),
- 'phone': '+2${phoneController.text}',
- 'email': box.read(BoxName.email),
- 'password': 'unknown',
- 'gender': 'unknown',
- 'birthdate': '2002-01-01',
- 'site': 'unknown',
- 'first_name': box.read(BoxName.name).toString().split(' ')[0],
- 'last_name': box.read(BoxName.name).toString().split(' ')[1],
- };
+ box.write(BoxName.phoneDriver, phoneController.text);
+ var nameParts = box.read(BoxName.name).toString().split(' ');
+ var firstName = nameParts.isNotEmpty ? nameParts[0] : 'unknown';
+ var lastName = nameParts.length > 1 ? nameParts[1] : 'unknown';
- var res1 = await CRUD().post(
- link: AppLink.signUp,
+ var payload = {
+ 'id': box.read(BoxName.passengerID),
+ 'phone': phoneController.text,
+ 'email': box.read(BoxName.email),
+ 'password': 'unknown',
+ 'gender': 'unknown',
+ 'birthdate': '2002-01-01',
+ 'site': box.read(BoxName.passengerPhotoUrl) ?? 'unknown',
+ 'first_name': firstName,
+ 'last_name': lastName,
+ };
+
+ var res1 = await CRUD().post(
+ link: AppLink.signUp,
+ payload: payload,
+ );
+
+ if (res1 != 'failure') {
+ await CRUD().post(
+ link: '${AppLink.seferAlexandriaServer}/auth/signup.php',
payload: payload,
);
- if (res1 != 'failure') {
- CRUD().post(
- link: '${AppLink.seferAlexandriaServer}/auth/signup.php',
- payload: payload,
- );
- CRUD().post(
- link: '${AppLink.seferGizaServer}/auth/signup.php',
- payload: payload,
- );
- box.write(BoxName.isVerified, '1');
- box.write(BoxName.phone, '+2${phoneController.text}');
- Get.offAll(const MapPagePassenger());
- }
- } else {
- Get.snackbar(
- 'Error'.tr, "The email or phone number is already registered.".tr,
- backgroundColor: Colors.redAccent);
+ await CRUD().post(
+ link: '${AppLink.seferGizaServer}/auth/signup.php',
+ payload: payload,
+ );
+
+ box.write(BoxName.isVerified, '1');
+ box.write(BoxName.isFirstTime, '0');
+ box.write(BoxName.phone, phoneController.text);
+
+ Get.put(LoginController()).loginUsingCredentials(
+ box.read(BoxName.passengerID).toString(),
+ box.read(BoxName.email).toString(),
+ );
}
+ // await controller.sendSmsEgypt(phoneNumber, otp.toString());
} else {
- var res = await CRUD().post(link: AppLink.verifyOtpMessage, payload: {
- 'phone_number': '+${phoneController.text}',
- 'token': verifyCode.text.toString(),
- });
- if (res != 'failure') {
- // var dec = jsonDecode(res);
- box.write(BoxName.phoneDriver, '+${phoneController.text}');
- var payload = {
- 'id': box.read(BoxName.passengerID),
- 'phone': '+${phoneController.text}',
- 'email': box.read(BoxName.email),
- 'password': 'unknown',
- 'gender': 'unknown',
- 'birthdate': '2002-01-01',
- 'site': 'unknown',
- 'first_name': box.read(BoxName.name).toString().split(' ')[0],
- 'last_name': box.read(BoxName.name).toString().split(' ')[1],
- };
+ await CRUD().sendWhatsAppAuth(phoneNumber, otp.toString());
+ }
+ isLoading = false;
- var res1 = await CRUD().post(
- link: AppLink.signUp,
- payload: payload,
- );
- if (res1 != 'failure') {
- CRUD().post(
- link: '${AppLink.seferAlexandriaServer}/auth/signup.php',
+ isSent = true;
+ remainingTime = 300;
+ update(); // Reset to 5 minutes
+ startTimer();
+ }
+
+ verifySMSCode() async {
+ try {
+ if (formKey3.currentState!.validate()) {
+ var res = await CRUD().post(link: AppLink.verifyOtpMessage, payload: {
+ 'phone_number': phoneController.text,
+ 'token': verifyCode.text.toString(),
+ });
+
+ if (res != 'failure') {
+ box.write(BoxName.phoneDriver, phoneController.text);
+ var nameParts = box.read(BoxName.name).toString().split(' ');
+ var firstName = nameParts.isNotEmpty ? nameParts[0] : 'unknown';
+ var lastName = nameParts.length > 1 ? nameParts[1] : 'unknown';
+
+ var payload = {
+ 'id': box.read(BoxName.passengerID),
+ 'phone': phoneController.text,
+ 'email': box.read(BoxName.email),
+ 'password': 'unknown',
+ 'gender': 'unknown',
+ 'birthdate': '2002-01-01',
+ 'site': box.read(BoxName.passengerPhotoUrl) ?? 'unknown',
+ 'first_name': firstName,
+ 'last_name': lastName,
+ };
+
+ var res1 = await CRUD().post(
+ link: AppLink.signUp,
payload: payload,
);
- CRUD().post(
- link: '${AppLink.seferGizaServer}/auth/signup.php',
- payload: payload,
- );
- box.write(BoxName.isVerified, '1');
- box.write(BoxName.phone, '+${phoneController.text}');
- Get.offAll(const MapPagePassenger());
+
+ if (res1 != 'failure') {
+ await CRUD().post(
+ link: '${AppLink.seferAlexandriaServer}/auth/signup.php',
+ payload: payload,
+ );
+ await CRUD().post(
+ link: '${AppLink.seferGizaServer}/auth/signup.php',
+ payload: payload,
+ );
+
+ box.write(BoxName.isVerified, '1');
+ box.write(BoxName.isFirstTime, '0');
+ box.write(BoxName.phone, phoneController.text);
+
+ Get.put(LoginController()).loginUsingCredentials(
+ box.read(BoxName.passengerID).toString(),
+ box.read(BoxName.email).toString(),
+ );
+ } else {
+ Get.snackbar('Error'.tr,
+ "The email or phone number is already registered.".tr,
+ backgroundColor: Colors.redAccent);
+ }
+ } else {
+ Get.snackbar('Error'.tr, "phone not verified".tr,
+ backgroundColor: Colors.redAccent);
}
} else {
- Get.snackbar(
- 'Error'.tr, "The email or phone number is already registered.".tr,
- backgroundColor: Colors.redAccent);
+ Get.snackbar('Error'.tr, "you must insert token code".tr,
+ backgroundColor: AppColor.redColor);
}
+ } catch (e) {
+ addError(e.toString(), 'passenger sign up ');
+ Get.snackbar('Error'.tr, "Something went wrong. Please try again.".tr,
+ backgroundColor: Colors.redAccent);
}
}
diff --git a/lib/controller/firebase/access_token.dart b/lib/controller/firebase/access_token.dart
index 1d81d88..93c6898 100644
--- a/lib/controller/firebase/access_token.dart
+++ b/lib/controller/firebase/access_token.dart
@@ -11,10 +11,9 @@ class AccessTokenManager {
factory AccessTokenManager(String jsonKey) {
if (_instance._isServiceAccountKeyInitialized()) {
- print('Service account key already initialized.');
+ // Prevent re-initialization
return _instance;
}
- print('Initializing service account key.');
_instance.serviceAccountJsonKey = jsonKey;
return _instance;
}
@@ -29,45 +28,23 @@ class AccessTokenManager {
}
Future getAccessToken() async {
- print('Attempting to get a new access token...');
-
+ if (_accessToken != null && DateTime.now().isBefore(_expiryDate!)) {
+ return _accessToken!.data;
+ }
try {
- // Parse service account credentials from JSON
- print('Parsing service account credentials...');
final serviceAccountCredentials = ServiceAccountCredentials.fromJson(
json.decode(serviceAccountJsonKey));
-
- // Log service account email (or other non-sensitive information)
- print('Service account email: ${serviceAccountCredentials.email}');
-
- // Create an authenticated client via the service account
- print('Creating authenticated client via service account...');
final client = await clientViaServiceAccount(
serviceAccountCredentials,
['https://www.googleapis.com/auth/firebase.messaging'],
);
- // Log successful client creation
- print('Authenticated client created successfully.');
-
- // Update the access token and expiry date
_accessToken = client.credentials.accessToken;
_expiryDate = client.credentials.accessToken.expiry;
-
- // Log the obtained token and expiry time
- print('Access token obtained: ${_accessToken!.data}');
- print('Token expiry date: $_expiryDate');
-
- // Close the client to prevent resource leaks
- print('Closing authenticated client...');
client.close();
-
- // Return the newly fetched access token
return _accessToken!.data;
} catch (e) {
- // Log error if token fetch fails
- print('Failed to obtain a new access token: $e');
- throw Exception('Failed to obtain a new access token: $e');
+ throw Exception('Failed to obtain access token');
}
}
}
diff --git a/lib/controller/firebase/firbase_messge.dart b/lib/controller/firebase/firbase_messge.dart
index f473004..18d324c 100644
--- a/lib/controller/firebase/firbase_messge.dart
+++ b/lib/controller/firebase/firbase_messge.dart
@@ -1,12 +1,9 @@
import 'dart:convert';
import 'dart:io';
-import 'package:SEFER/env/env.dart';
import 'package:SEFER/views/widgets/my_dialog.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
-import 'package:googleapis_auth/auth_io.dart';
-import 'package:googleapis_auth/googleapis_auth.dart';
import 'package:http/http.dart' as http;
import 'package:SEFER/controller/functions/toast.dart';
import 'package:SEFER/views/widgets/elevated_btn.dart';
@@ -69,6 +66,9 @@ class FirebaseMessagesController extends GetxController {
}
}
+ NotificationController notificationController =
+ Get.put(NotificationController());
+
Future getTokens() async {
String? basicAuthCredentials =
await storage.read(key: BoxName.basicAuthCredentials);
@@ -122,7 +122,15 @@ class FirebaseMessagesController extends GetxController {
void fireBaseTitles(RemoteMessage message) {
if (message.notification!.title! == 'Order'.tr) {
- } else if (message.notification!.title! == 'Apply Ride'.tr) {
+ if (Platform.isAndroid) {
+ notificationController.showNotification(
+ 'Order', message.notification!.body!, 'Order');
+ }
+ } else if (message.notification!.title! == 'Accepted Ride') {
+ if (Platform.isAndroid) {
+ notificationController.showNotification(
+ 'Apply Order'.tr, 'Driver Applied the Ride for You'.tr, 'ding');
+ }
var passengerList = message.data['passengerList'];
var myList = jsonDecode(passengerList) as List;
@@ -131,16 +139,20 @@ class FirebaseMessagesController extends GetxController {
Get.find().statusRide == 'Apply';
Get.find().isSearchingWindow == false;
Get.find().update();
- NotificationController().showNotification(
- 'Apply Order'.tr, 'Driver Applied the Ride for You'.tr, 'order1');
+ Get.find().rideAppliedFromDriver(true);
+
// driverAppliedTripSnakBar();
} else if (message.notification!.title! == 'Promo'.tr) {
- NotificationController()
- .showNotification('Promo', 'Show latest promo'.tr, 'promo');
+ if (Platform.isAndroid) {
+ notificationController.showNotification(
+ 'Promo', 'Show latest promo'.tr, 'promo');
+ }
Get.to(const PromosPassengerPage());
} else if (message.notification!.title! == 'Trip Monitoring'.tr) {
- NotificationController()
- .showNotification('Trip Monitoring'.tr, '', 'iphone_ringtone');
+ if (Platform.isAndroid) {
+ notificationController.showNotification(
+ 'Trip Monitoring'.tr, '', 'iphone_ringtone');
+ }
var myListString = message.data['passengerList'];
var myList = jsonDecode(myListString) as List;
Get.toNamed('/tripmonitor', arguments: {
@@ -148,53 +160,72 @@ class FirebaseMessagesController extends GetxController {
'driverId': myList[1].toString(),
});
} else if (message.notification!.title! == 'token change'.tr) {
- NotificationController()
- .showNotification('token change'.tr, 'token change'.tr, 'cancel');
+ if (Platform.isAndroid) {
+ notificationController.showNotification(
+ 'token change'.tr, 'token change'.tr, 'cancel');
+ }
GoogleSignInHelper.signOut();
} else if (message.notification!.title! == 'DriverIsGoingToPassenger'.tr) {
Get.find().isDriverInPassengerWay = true;
Get.find().update();
- NotificationController().showNotification('Driver is Going To You'.tr,
- 'Please stay on the picked point.'.tr, 'tone1');
+ if (Platform.isAndroid) {
+ notificationController.showNotification('Driver is Going To You'.tr,
+ 'Please stay on the picked point.'.tr, 'tone1');
+ }
// Get.snackbar('Driver is Going To Passenger', '',
// backgroundColor: AppColor.greenColor);
} else if (message.notification!.title! == 'message From passenger') {
- NotificationController()
- .showNotification('message From passenger'.tr, ''.tr, 'tone2');
+ if (Platform.isAndroid) {
+ notificationController.showNotification(
+ 'message From passenger'.tr, ''.tr, 'ding');
+ }
passengerDialog(message.notification!.body!);
update();
} else if (message.notification!.title! == 'message From Driver') {
- NotificationController()
- .showNotification('message From passenger'.tr, ''.tr, 'tone2');
+ if (Platform.isAndroid) {
+ notificationController.showNotification(
+ 'message From Driver'.tr, ''.tr, 'ding');
+ }
passengerDialog(message.notification!.body!);
update();
} else if (message.notification!.title! == 'RideIsBegin'.tr) {
+ if (Platform.isAndroid) {
+ notificationController.showNotification(
+ 'Trip is Begin'.tr, ''.tr, 'start');
+ }
Get.find().getBeginRideFromDriver();
// Get.snackbar('RideIsBegin', '', backgroundColor: AppColor.greenColor);
box.write(BoxName.passengerWalletTotal, '0');
- NotificationController()
- .showNotification('Trip is Begin'.tr, ''.tr, 'start');
update();
} else if (message.notification!.title! == 'Hi ,I will go now'.tr) {
// Get.snackbar('Hi ,I will go now', '',
// backgroundColor: AppColor.greenColor);
- NotificationController().showNotification(
- 'Passenger come to you'.tr, 'Hi ,I will go now'.tr, 'tone2');
+ if (Platform.isAndroid) {
+ notificationController.showNotification(
+ 'Passenger come to you'.tr, 'Hi ,I will go now'.tr, 'ding');
+ }
update();
- } else if (message.notification!.title! == 'Hi ,I Arrive your site'.tr) {
- NotificationController()
- .showNotification('Hi ,I Arrive your site'.tr, ''.tr, 'tone2');
+ } else if (message.notification!.title! == 'Hi ,I Arrive your site') {
+ if (Platform.isAndroid) {
+ notificationController.showNotification(
+ 'Hi ,I Arrive your site'.tr, ''.tr, 'ding');
+ }
driverArrivePassengerDialoge();
update();
- } else if (message.notification!.title! == "Cancel Trip from driver".tr) {
+ } else if (message.notification!.title! == "Cancel Trip from driver") {
Get.back();
+ if (Platform.isAndroid) {
+ notificationController.showNotification("Cancel Trip from driver".tr,
+ "We will look for a new driver.\nPlease wait.".tr, 'cancel');
+ }
Get.defaultDialog(
title: "The driver canceled your ride.".tr,
- middleText: "We will look for a new driver.\\nPlease wait.".tr,
+ middleText: "We will look for a new driver.\nPlease wait.".tr,
confirm: MyElevatedButton(
+ kolor: AppColor.greenColor,
title: 'Ok'.tr,
onPressed: () async {
Get.back();
@@ -204,32 +235,38 @@ class FirebaseMessagesController extends GetxController {
),
cancel: MyElevatedButton(
title: 'Cancel'.tr,
+ kolor: AppColor.redColor,
onPressed: () {
- Get.offAll(const MapPagePassenger());
+ Get.offAll(() => const MapPagePassenger());
},
)
// Get.find()
// .searchNewDriverAfterRejectingFromDriver();
);
} else if (message.notification!.title! == 'Driver Finish Trip'.tr) {
- var myListString = message.data['passengerList'];
+ var myListString = message.data['DriverList'];
var driverList = jsonDecode(myListString) as List;
- NotificationController().showNotification(
- 'Driver Finish Trip'.tr,
- 'you will pay to Driver'.tr + ' ${driverList[3].toString()} \$'.tr,
- 'tone1');
+ if (Platform.isAndroid) {
+ notificationController.showNotification(
+ 'Driver Finish Trip'.tr,
+ 'you will pay to Driver'.tr + ' ${driverList[3].toString()} \$'.tr,
+ 'tone1');
+ }
Get.find().stopRecording();
if (double.parse(box.read(BoxName.passengerWalletTotal)) < 0) {
box.write(BoxName.passengerWalletTotal, 0);
}
Get.find().tripFinishedFromDriver();
-
+ notificationController.showNotification(
+ 'Don’t forget your personal belongings.'.tr,
+ 'Please make sure you have all your personal belongings and that any remaining fare, if applicable, has been added to your wallet before leaving. Thank you for choosing the Sefer app'
+ .tr,
+ 'ding');
Get.to(() => RateDriverFromPassenger(), arguments: {
'driverId': driverList[0].toString(),
'rideId': driverList[1].toString(),
'price': driverList[3].toString()
});
- // }
} else if (message.notification!.title! == "Finish Monitor".tr) {
Get.defaultDialog(
titleStyle: AppStyle.title,
@@ -249,11 +286,13 @@ class FirebaseMessagesController extends GetxController {
var myListString = message.data['passengerList'];
var driverList = jsonDecode(myListString) as List;
// if (Platform.isAndroid) {
- NotificationController().showNotification(
- 'Call Income'.tr,
- message.notification!.body!,
- 'iphone_ringtone',
- );
+ if (Platform.isAndroid) {
+ notificationController.showNotification(
+ 'Call Income'.tr,
+ message.notification!.body!,
+ 'iphone_ringtone',
+ );
+ }
// }
// Assuming GetMaterialApp is initialized and context is valid for navigation
// Get.to(() => PassengerCallPage(
@@ -267,12 +306,13 @@ class FirebaseMessagesController extends GetxController {
var myListString = message.data['passengerList'];
var driverList = jsonDecode(myListString) as List;
// if (Platform.isAndroid) {
- NotificationController().showNotification(
- 'Call Income'.tr,
- message.notification!.body!,
- 'iphone_ringtone',
- );
- // }
+ if (Platform.isAndroid) {
+ notificationController.showNotification(
+ 'Call Income'.tr,
+ message.notification!.body!,
+ 'iphone_ringtone',
+ );
+ }
// Assuming GetMaterialApp is initialized and context is valid for navigation
// Get.to(() => PassengerCallPage(
// channelName: driverList[1].toString(),
@@ -285,24 +325,24 @@ class FirebaseMessagesController extends GetxController {
var myListString = message.data['passengerList'];
var driverList = jsonDecode(myListString) as List;
if (Platform.isAndroid) {
- NotificationController().showNotification(
+ notificationController.showNotification(
'Call End'.tr,
message.notification!.body!,
- 'tone2',
+ 'ding',
);
}
// Assuming GetMaterialApp is initialized and context is valid for navigation
// Get.off(const CallPage());
} catch (e) {}
- } else if (message.notification!.title! == 'Driver Cancel Your Trip'.tr) {
+ } else if (message.notification!.title! == 'Driver Cancelled Your Trip') {
// Get.snackbar(
// 'You will be pay the cost to driver or we will get it from you on next trip'
// .tr,
// 'message',
// backgroundColor: AppColor.redColor);
if (Platform.isAndroid) {
- NotificationController().showNotification(
- 'Driver Cancel Your Trip'.tr,
+ notificationController.showNotification(
+ 'Driver Cancelled Your Trip'.tr,
'you will pay to Driver you will be pay the cost of driver time look to your SEFER Wallet'
.tr,
'cancel');
@@ -311,7 +351,7 @@ class FirebaseMessagesController extends GetxController {
box.remove(BoxName.tokenParent);
Get.find().restCounter();
- Get.offAll(const MapPagePassenger());
+ Get.offAll(() => const MapPagePassenger());
}
// else if (message.notification!.title! == 'Order Applied') {
// Get.snackbar(
@@ -325,38 +365,13 @@ class FirebaseMessagesController extends GetxController {
// }
else if (message.notification!.title! == 'Order Applied'.tr) {
- NotificationController().showNotification(
- 'The order Accepted by another Driver'.tr,
- 'We regret to inform you that another driver has accepted this order.'
- .tr,
- 'order');
- } else if (message.notification!.title! == 'VIP Order Accepted'.tr) {
- var myListString = message.data['passengerList'];
- var driverList = jsonDecode(myListString) as List;
-
- // Assuming driverList[1] contains a valid date string
- DateTime scheduledTime;
- try {
- scheduledTime = DateTime.parse(driverList[1]);
- } catch (e) {
- // Handle the error if the date format is incorrect
- Log.print('Error parsing date: $e');
- scheduledTime = DateTime.now()
- .add(const Duration(hours: 1)); // Fallback to 1 hour from now
+ if (Platform.isAndroid) {
+ notificationController.showNotification(
+ 'The order Accepted by another Driver'.tr,
+ 'We regret to inform you that another driver has accepted this order.'
+ .tr,
+ 'order');
}
-
- NotificationController()
- .showNotification('The driver accepted your trip'.tr, '', 'order');
-
- MyDialog().getDialog(
- 'VIP Order Accepted'.tr,
- 'The driver accepted your trip'.tr,
- () {
- // Schedule a notification for the parsed date or fallback date
- NotificationController().scheduleNotification('VIP Order'.tr,
- 'This is a scheduled notification.'.tr, scheduledTime);
- },
- );
}
}
@@ -393,7 +408,7 @@ class FirebaseMessagesController extends GetxController {
title: 'Ok I will go now.'.tr,
onPressed: () {
FirebaseMessagesController().sendNotificationToPassengerToken(
- 'Hi ,I will go now'.tr,
+ 'Hi ,I will go now',
'I will go now'.tr,
Get.find().driverToken,
[],
@@ -410,7 +425,7 @@ class FirebaseMessagesController extends GetxController {
Future passengerDialog(String message) {
return Get.defaultDialog(
barrierDismissible: false,
- title: 'message From passenger'.tr,
+ title: 'message From Driver'.tr,
titleStyle: AppStyle.title,
middleTextStyle: AppStyle.title,
middleText: message.tr,
@@ -456,7 +471,7 @@ class FirebaseMessagesController extends GetxController {
));
}
- void sendNotificationAll(String title, body) async {
+ void sendNotificationAll(String title, body, tone) async {
// Get the token you want to subtract.
String token = box.read(BoxName.tokenFCM);
tokens = box.read(BoxName.tokens);
@@ -468,25 +483,41 @@ class FirebaseMessagesController extends GetxController {
tokens = box.read(BoxName.tokens);
for (var i = 0; i < tokens.length; i++) {
http
- .post(Uri.parse('https://fcm.googleapis.com/fcm/send'),
- headers: {
- 'Content-Type': 'application/json',
- 'Authorization': 'key=${AK.serverAPI}'
- },
- body: jsonEncode({
- 'notification': {
+ .post(
+ Uri.parse('https://fcm.googleapis.com/fcm/send'),
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': 'key=${AK.serverAPI}'
+ },
+ body: jsonEncode({
+ 'message': {
+ 'token': token,
+ 'notification': {
'title': title,
'body': body,
- 'sound': 'ding.wav'
},
- 'priority': 'high',
- 'data': {
- 'click_action': 'FLUTTER_NOTIFICATION_CLICK',
- 'id': '1',
- 'status': 'done'
+ // 'data': {
+ // 'DriverList': jsonEncode(data),
+ // },
+ 'android': {
+ 'priority': 'high', // Set priority to high
+ 'notification': {
+ 'sound': tone,
+ },
},
- 'to': tokens[i],
- }))
+ 'apns': {
+ 'headers': {
+ 'apns-priority': '10', // Set APNs priority to 10
+ },
+ 'payload': {
+ 'aps': {
+ 'sound': tone,
+ },
+ },
+ },
+ },
+ }),
+ )
.whenComplete(() {})
.catchError((e) {});
}
@@ -521,40 +552,6 @@ class FirebaseMessagesController extends GetxController {
void sendNotificationToPassengerToken(
String title, body, token, List map, String tone) async {
- try {
- final response = await http.post(
- Uri.parse('https://fcm.googleapis.com/fcm/send'),
- headers: {
- 'Content-Type': 'application/json',
- 'Authorization': 'key=${AK.serverAPI}'
- },
- body: jsonEncode({
- 'notification': {
- 'title': title,
- 'body': body,
- 'sound': tone
- },
- 'data': {
- 'passengerList': map,
- },
- 'priority': 'high',
- 'to': token,
- }),
- );
-
- if (response.statusCode == 200) {
- // Notification sent successfully
- } else {
- // Handle error response
- 'Failed to send notification. Status code: ${response.statusCode}';
- }
- } catch (e) {
- // Handle other exceptions
- }
- }
-
- void sendNotificationToAnyWithoutData(
- String title, String body, String token, String tone) async {
try {
String serviceAccountKeyJson = '''{
"type": "service_account",
@@ -594,11 +591,15 @@ class FirebaseMessagesController extends GetxController {
'body': body,
},
'android': {
+ 'priority': 'high', // Set priority to high
'notification': {
'sound': tone,
},
},
'apns': {
+ 'headers': {
+ 'apns-priority': '10', // Set APNs priority to 10
+ },
'payload': {
'aps': {
'sound': tone,
@@ -610,75 +611,22 @@ class FirebaseMessagesController extends GetxController {
);
if (response.statusCode == 200) {
- print('Notification sent successfully.');
+ print(
+ 'Notification sent successfully. Status code: ${response.statusCode}');
print('Response body: ${response.body}');
} else {
print(
'Failed to send notification. Status code: ${response.statusCode}');
print('Response body: ${response.body}');
-
- // Parse the response body to handle specific errors like 'UNREGISTERED'
- final responseBody = jsonDecode(response.body);
- if (responseBody['error'] != null &&
- responseBody['error']['status'] == 'NOT_FOUND' &&
- responseBody['error']['details'] != null) {
- for (var detail in responseBody['error']['details']) {
- if (detail['errorCode'] == 'UNREGISTERED') {
- print(
- 'FCM token is unregistered or invalid. Consider removing this token.');
- // Remove the unregistered token from your database here.
- // Example: removeTokenFromDatabase(token);
- }
- }
- }
}
} catch (e) {
print('Error sending notification: $e');
}
}
- // void sendNotificationToDriverMAP(String title, String body, String token,
- // List data, String tone) async {
- // try {
- // final response = await http.post(
- // // Uri.parse(
- // // 'https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send'),
- // Uri.parse('https://fcm.googleapis.com/fcm/send'),
- // headers: {
- // 'Content-Type': 'application/json',
- // // 'Authorization': 'Bearer 104815009508844392546'
- // 'Authorization': 'key=${AK.serverAPI}'
- // },
- // body: jsonEncode({
- // 'notification': {
- // 'title': title,
- // 'body': body,
- // 'sound': tone
- // },
- // 'data': {
- // 'DriverList': data,
- // },
- // 'priority': 'high',
- // 'to': token,
- // }),
- // );
-
- // if (response.statusCode == 200) {
- // Log.print(
- // 'Notification sent successfully. Status code: ${response.statusCode}');
- // Log.print('Response body: ${response.body}');
- // } else {
- // Log.print(
- // 'Failed to send notification. Status code: ${response.statusCode}');
- // Log.print('Response body: ${response.body}');
- // }
- // } catch (e) {
- // Log.print('Error sending notification: $e');
- // }
- // }
-
- Future sendNotificationToDriverMAP(String title, String body,
- String token, List data, String tone) async {
+ Future sendNotificationToDriverMAP(
+ String title, String body, String token, List data, String tone,
+ {int retryCount = 2}) async {
try {
String serviceAccountKeyJson = '''{
"type": "service_account",
@@ -700,7 +648,7 @@ class FirebaseMessagesController extends GetxController {
// Obtain an OAuth 2.0 access token
final accessToken = await accessTokenManager.getAccessToken();
- Log.print('accessToken: ${accessToken}');
+ // Log.print('accessToken: ${accessToken}');
// Send the notification
final response = await http.post(
@@ -721,11 +669,15 @@ class FirebaseMessagesController extends GetxController {
'DriverList': jsonEncode(data),
},
'android': {
+ 'priority': 'high', // Set priority to high
'notification': {
'sound': tone,
},
},
'apns': {
+ 'headers': {
+ 'apns-priority': '10', // Set APNs priority to 10
+ },
'payload': {
'aps': {
'sound': tone,
@@ -735,105 +687,32 @@ class FirebaseMessagesController extends GetxController {
},
}),
);
+
if (response.statusCode == 200) {
- print('Notification sent successfully.');
- print('Response body: ${response.body}');
+ print(
+ 'Notification sent successfully. Status code: ${response.statusCode}');
+ print('Response token: ${token}');
} else {
print(
'Failed to send notification. Status code: ${response.statusCode}');
print('Response body: ${response.body}');
-
- // Parse the response body to handle specific errors like 'UNREGISTERED'
- final responseBody = jsonDecode(response.body);
- if (responseBody['error'] != null &&
- responseBody['error']['status'] == 'NOT_FOUND' &&
- responseBody['error']['details'] != null) {
- for (var detail in responseBody['error']['details']) {
- if (detail['errorCode'] == 'UNREGISTERED') {
- print(
- 'FCM token is unregistered or invalid. Consider removing this token.');
- // Remove the unregistered token from your database if needed
- }
- }
+ if (retryCount > 0) {
+ print('Retrying... Attempts remaining: $retryCount');
+ await Future.delayed(
+ Duration(seconds: 2)); // Optional delay before retrying
+ return sendNotificationToDriverMAP(title, body, token, data, tone,
+ retryCount: retryCount - 1);
}
}
} catch (e) {
print('Error sending notification: $e');
- }
- }
-
- void sendNotificationToDriverMapPolyline(String title, String body,
- String token, List data, String polylineJson) async {
- try {
- String serviceAccountKeyJson = '''{
- "type": "service_account",
- "project_id": "ride-b1bd8",
- "private_key_id": "75e817c0b902db2ef35edf2c2bd159dec1f13249",
- "private_key": "-----BEGIN PRIVATE KEY-----\\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD0zH9TQGDQHUv3\\na3/JAD1UKPwAp3wNKT0a6fxiIzjI3JxQWI30QvZCcfl6CdMhIcydX1ncSaYTcEeC\\n/AdPVCPkqyJx1YIGGg6P/mRzCWeaN8fsp6z250m5vcObDCZc3dbJEkepbep+6FPY\\n21m3KO+AHh1glgsTGZOTm5xiU8NGXpdk2QEh8wpiIIlR/HuKwVw9g8urNe3Sno+U\\nDm3z37iFqvZdmpqO8aWTJu6beb3hsREK9XK2I9JqC2JUwiGQRo3idOvPP6hkqrWx\\nKSX96vglQFYfakvJdDp2ZATOlpBYPMtS/IWhJ985u58TSS+Kl8qpnpaZBSxgJirf\\nhWzhnKLfAgMBAAECggEAJP785SePGhS7ZN6ltspm+l+hSjYFrPWFCxq+rlQ1YkHZ\\nC9l+RqKSFhOkiPmQI2s4wbXl3kFxLHHlFNoi/q2wKQBmGb8TQfnRJpjjNHGA61Ev\\n0Ue7/6qPvVb9B2MsLw/FxKiTFPuMG3bgKR9pbSFuJLYoaW7zqITOhVnYphGTqwAY\\nBVVcvISSLvELDmH9VZcv/9DVqVlqbbESHWh1Z4W6XGPoEqeDH/upNTyQQ/46Msgm\\nTGE6VqLHpWuSf6SqHp+r0Y0lI3vIPM1vz5FAJDJbOE/enHa0fSup0OHSMxl0HVMn\\nnO1yrGF3vsIPOej5HKr5d71bEIckzk73/yjNC1/mDQKBgQD7RtUvc9omsSsFMJ6e\\nBASAn6Dktx/QY/XNJjFzHQj69cywLDe5t5AL2gUi3phQ2oqB5XJdwnd5bTIEPEPZ\\nDOuOai2802p6FJk6kjmZAMVGx5JtXBH+vs6jrmQQSMiKbjwN1TT6xIWakvLOonUi\\nX6ZvjYYjU/E0YJU3jSiXWEr76wKBgQD5Zn4SouJ6BCDZMbausJVMBkk3qxsYooip\\np89WakC6e7AZinpkRcqjGGV9GOvc8crJs6fyXAA9ORepGP47Mc0ZrDssOkstznsM\\npr8R0S6MKwEZaT9ixOHdOcLZ47ps+JzA2Wr4KN2OvFHksUkB/46ATD1j9WZVgB8M\\namsYp/Y73QKBgHOo+PvsoZ9psVmkNX6abtAdqdtdB0HOoRea2uwXk0ig12TIFaZg\\nfedWpUKVnxqoXVTJHklV99RmlL0qWDiSH+LfsMnXro0e6iDxqZ1po2Se/CFmXcoa\\nXdctsFVmixhdATuExewfhTfPKABA+xWlXWC/jdy5CK+JPWXijaqMM4edAoGAE5Bj\\nsWiPpYyvWvpYX0nA3G7dzX0hqgQN/mkIjbnWDArp3IcNZNJIvBSM2Yxb7EAXbU0n\\njo6DAkp5Pa2VO+WDNlFZbvW/sf8xjeOCt44WPa6d7nVgIIpbQXRngZoopKW3/jTP\\n/FmQT8McFXmGxZ5belsAsdetSGW9icbLUerTGQ0CgYEAmf/G8Ag3XxmqTXvvHuv2\\n14OP7WnrVqkEMnydrftEwn4peXd/Lz+/GYX5Zc4ZoNgbN8IvZ5z0+OmRsallsbiW\\nBw0/tc68CjzxXOvReWxDluUopqWVGj5tlGqE5xUDku9SWJSxbkiQ3rqutzBdPXpr\\noqHwPyDrmK/Zgqn+uiIm4Ck=\\n-----END PRIVATE KEY-----\\n",
- "client_email": "firebase-adminsdk-o2wqi@ride-b1bd8.iam.gserviceaccount.com",
- "client_id": "111210077025005706623",
- "auth_uri": "https://accounts.google.com/o/oauth2/auth",
- "token_uri": "https://oauth2.googleapis.com/token",
- "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
- "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-o2wqi%40ride-b1bd8.iam.gserviceaccount.com",
- "universe_domain": "googleapis.com"
-}
-'''; // As defined above
-
- // Initialize AccessTokenManager
- final accessTokenManager = AccessTokenManager(serviceAccountKeyJson);
-
- // Obtain an OAuth 2.0 access token
- final accessToken = await accessTokenManager.getAccessToken();
-
- // Send the notification
- final response = await http.post(
- Uri.parse(
- 'https://fcm.googleapis.com/v1/projects/ride-b1bd8/messages:send'),
- headers: {
- 'Content-Type': 'application/json',
- 'Authorization': 'Bearer $accessToken',
- },
- body: jsonEncode({
- 'notification': {
- 'title': title,
- 'body': body,
- // 'sound': 'tone2.wav',
- 'sound': 'order.wav'
- },
- 'data': {
- 'DriverList': data,
- 'PolylineJson': polylineJson,
- },
- 'priority': 'high',
- 'to': token,
- }),
- );
-
- if (response.statusCode == 200) {
- print('Notification sent successfully.');
- print('Response body: ${response.body}');
- } else {
- print(
- 'Failed to send notification. Status code: ${response.statusCode}');
- print('Response body: ${response.body}');
-
- // Parse the response body to handle specific errors like 'UNREGISTERED'
- final responseBody = jsonDecode(response.body);
- if (responseBody['error'] != null &&
- responseBody['error']['status'] == 'NOT_FOUND' &&
- responseBody['error']['details'] != null) {
- for (var detail in responseBody['error']['details']) {
- if (detail['errorCode'] == 'UNREGISTERED') {
- print(
- 'FCM token is unregistered or invalid. Consider removing this token.');
- // Remove the unregistered token from your database if needed
- }
- }
- }
+ if (retryCount > 0) {
+ print('Retrying... Attempts remaining: $retryCount');
+ await Future.delayed(
+ Duration(seconds: 2)); // Optional delay before retrying
+ return sendNotificationToDriverMAP(title, body, token, data, tone,
+ retryCount: retryCount - 1);
}
- } catch (e) {
- // Handle other exceptions
}
}
}
diff --git a/lib/controller/firebase/local_notification.dart b/lib/controller/firebase/local_notification.dart
index fc28a8e..fb2fc26 100644
--- a/lib/controller/firebase/local_notification.dart
+++ b/lib/controller/firebase/local_notification.dart
@@ -1,8 +1,14 @@
+import 'dart:async';
+import 'dart:io';
+
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:get/get.dart';
+import 'package:permission_handler/permission_handler.dart';
import 'package:timezone/data/latest.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
+import '../../main.dart';
+
class NotificationController extends GetxController {
final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
@@ -11,53 +17,315 @@ class NotificationController extends GetxController {
void onInit() {
super.onInit();
initNotifications();
- tz.initializeTimeZones();
}
// Initializes the local notifications plugin
Future initNotifications() async {
const AndroidInitializationSettings android =
AndroidInitializationSettings('@mipmap/launcher_icon');
- const InitializationSettings initializationSettings =
- InitializationSettings(android: android);
+ DarwinInitializationSettings ios = DarwinInitializationSettings(
+ requestAlertPermission: true,
+ requestBadgePermission: true,
+ requestSoundPermission: true,
+ onDidReceiveLocalNotification:
+ (int id, String? title, String? body, String? payload) async {},
+ );
+ InitializationSettings initializationSettings =
+ InitializationSettings(android: android, iOS: ios);
await _flutterLocalNotificationsPlugin.initialize(initializationSettings);
+
+ tz.initializeTimeZones();
+ print('Notifications initialized');
}
// Displays a notification with the given title and message
void showNotification(String title, String message, String tone) async {
- AndroidNotificationDetails android = AndroidNotificationDetails(
- 'your channel id', 'your channel name',
- importance: Importance.max,
- priority: Priority.high,
- showWhen: false,
- sound: RawResourceAndroidNotificationSound(tone));
+ final AndroidNotificationDetails android = AndroidNotificationDetails(
+ 'high_importance_channel',
+ 'High Importance Notifications',
+ importance: Importance.max,
+ priority: Priority.high,
+ showWhen: false,
+ sound: RawResourceAndroidNotificationSound(tone),
+ );
- NotificationDetails details = NotificationDetails(android: android);
+ const DarwinNotificationDetails ios = DarwinNotificationDetails(
+ sound: 'default',
+ presentAlert: true,
+ presentBadge: true,
+ presentSound: true,
+ );
+
+ final NotificationDetails details =
+ NotificationDetails(android: android, iOS: ios);
await _flutterLocalNotificationsPlugin.show(0, title, message, details);
+ print('Notification shown: $title - $message');
+ }
+// /Users/hamzaaleghwairyeen/development/App/ride 2/lib/controller/firebase/local_notification.dart
+
+// Assume _flutterLocalNotificationsPlugin is initialized somewhere in your code
+
+ // void scheduleNotificationsForSevenDays(
+ // String title, String message, String tone) async {
+ // final AndroidNotificationDetails android = AndroidNotificationDetails(
+ // 'high_importance_channel',
+ // 'High Importance Notifications',
+ // importance: Importance.max,
+ // priority: Priority.high,
+ // sound: RawResourceAndroidNotificationSound(tone),
+ // );
+
+ // const DarwinNotificationDetails ios = DarwinNotificationDetails(
+ // sound: 'default',
+ // presentAlert: true,
+ // presentBadge: true,
+ // presentSound: true,
+ // );
+
+ // final NotificationDetails details =
+ // NotificationDetails(android: android, iOS: ios);
+
+ // // Check for the exact alarm permission on Android 12 and above
+ // if (Platform.isAndroid) {
+ // if (await Permission.scheduleExactAlarm.isDenied) {
+ // if (await Permission.scheduleExactAlarm.request().isGranted) {
+ // print('SCHEDULE_EXACT_ALARM permission granted');
+ // } else {
+ // print('SCHEDULE_EXACT_ALARM permission denied');
+ // return;
+ // }
+ // }
+ // }
+
+ // // Schedule notifications for the next 7 days
+ // for (int day = 0; day < 7; day++) {
+ // // Schedule for 8:00 AM
+ // await _scheduleNotificationForTime(
+ // day, 8, 0, title, message, details, day * 1000 + 1);
+
+ // // 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');
+ // }
+ void scheduleNotificationsForSevenDays(
+ String title, String message, String tone) async {
+ final AndroidNotificationDetails android = AndroidNotificationDetails(
+ 'high_importance_channel',
+ 'High Importance Notifications',
+ importance: Importance.max,
+ priority: Priority.high,
+ sound: RawResourceAndroidNotificationSound(tone),
+ );
+
+ const DarwinNotificationDetails ios = DarwinNotificationDetails(
+ sound: 'default',
+ presentAlert: true,
+ presentBadge: true,
+ presentSound: true,
+ );
+
+ final NotificationDetails details =
+ NotificationDetails(android: android, iOS: ios);
+
+ // Check for the exact alarm permission on Android 12 and above
+ if (Platform.isAndroid) {
+ if (await Permission.scheduleExactAlarm.isDenied) {
+ if (await Permission.scheduleExactAlarm.request().isGranted) {
+ print('SCHEDULE_EXACT_ALARM permission granted');
+ } else {
+ print('SCHEDULE_EXACT_ALARM permission denied');
+ return;
+ }
+ }
+ }
+
+ // Schedule notifications for the next 7 days
+ for (int day = 0; day < 7; day++) {
+ // List of notification times
+ final notificationTimes = [
+ {'hour': 8, 'minute': 0, 'id': day * 1000 + 1}, // 8:00 AM
+ {'hour': 15, 'minute': 0, 'id': day * 1000 + 2}, // 3:00 PM
+ {'hour': 20, 'minute': 0, 'id': day * 1000 + 3}, // 8:00 PM
+ ];
+
+ for (var time in notificationTimes) {
+ final notificationId = time['id'] as int;
+
+ // Check if this notification ID is already stored
+ bool isScheduled = box.read('notification_$notificationId') ?? false;
+
+ if (!isScheduled) {
+ // Schedule the notification if not already scheduled
+ await _scheduleNotificationForTime(
+ day,
+ time['hour'] as int,
+ time['minute'] as int,
+ title,
+ message,
+ details,
+ notificationId,
+ );
+
+ // Mark this notification ID as scheduled in GetStorage
+ box.write('notification_$notificationId', true);
+ } else {
+ print('Notification with ID $notificationId is already scheduled.');
+ }
+ }
+ }
+
+ print('Notifications scheduled successfully for the next 7 days');
}
- // Schedules a notification for a specific time
- Future scheduleNotification(
- String title, String body, DateTime scheduledTime) async {
- await _flutterLocalNotificationsPlugin.zonedSchedule(
- 0,
+ void scheduleNotificationsForTimeSelected(
+ String title, String message, String tone, DateTime timeSelected) async {
+ final AndroidNotificationDetails android = AndroidNotificationDetails(
+ 'high_importance_channel',
+ 'High Importance Notifications',
+ importance: Importance.max,
+ priority: Priority.high,
+ sound: RawResourceAndroidNotificationSound(tone),
+ );
+
+ const DarwinNotificationDetails ios = DarwinNotificationDetails(
+ sound: 'default',
+ presentAlert: true,
+ presentBadge: true,
+ presentSound: true,
+ );
+
+ final NotificationDetails details =
+ NotificationDetails(android: android, iOS: ios);
+
+ // Check for the exact alarm permission on Android 12 and above
+ if (Platform.isAndroid) {
+ if (await Permission.scheduleExactAlarm.isDenied) {
+ if (await Permission.scheduleExactAlarm.request().isGranted) {
+ print('SCHEDULE_EXACT_ALARM permission granted');
+ } else {
+ print('SCHEDULE_EXACT_ALARM permission denied');
+ return;
+ }
+ }
+ }
+
+ // Schedule notifications for 10 and 30 minutes before the timeSelected
+ await _scheduleNotificationForTimeVIP(
+ timeSelected.subtract(const Duration(minutes: 10)), // 10 minutes before
title,
- body,
- tz.TZDateTime.from(scheduledTime, tz.local),
- const NotificationDetails(
- android: AndroidNotificationDetails(
- 'your_channel_id',
- 'your_channel_name',
- channelDescription: 'your_channel_description',
- importance: Importance.max,
- priority: Priority.high,
- showWhen: false,
- ),
- ),
- androidAllowWhileIdle: true,
+ message,
+ details,
+ 1, // Unique ID for 10-minute before notification
+ );
+
+ await _scheduleNotificationForTimeVIP(
+ timeSelected.subtract(const Duration(minutes: 30)), // 30 minutes before
+ title,
+ message,
+ details,
+ 2, // Unique ID for 30-minute before notification
+ );
+
+ print('Notifications scheduled successfully for the time selected');
+ }
+
+ Future _scheduleNotificationForTimeVIP(
+ DateTime scheduledDate,
+ String title,
+ String message,
+ NotificationDetails details,
+ int notificationId,
+ ) async {
+ // Initialize and set Cairo timezone
+ tz.initializeTimeZones();
+ var cairoLocation = tz.getLocation('Africa/Cairo');
+
+ final now = tz.TZDateTime.now(cairoLocation);
+
+ // Convert to Cairo time
+ tz.TZDateTime scheduledTZDateTime =
+ tz.TZDateTime.from(scheduledDate, cairoLocation);
+
+ // Check if 10 minutes before the scheduled time is in the past
+ if (scheduledTZDateTime
+ .subtract(const Duration(minutes: 10))
+ .isBefore(now)) {
+ // If the 10 minutes before the scheduled time is in the past, don't schedule
+ print(
+ 'Scheduled time minus 10 minutes is in the past. Skipping notification.');
+ return; // Skip this notification
+ }
+
+ print('Current time (Cairo): $now');
+ print('Scheduling notification for: $scheduledTZDateTime');
+
+ await _flutterLocalNotificationsPlugin.zonedSchedule(
+ notificationId, // Unique ID for each notification
+ title,
+ message,
+ scheduledTZDateTime,
+ details,
+ androidScheduleMode: AndroidScheduleMode.exact,
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation.absoluteTime,
- matchDateTimeComponents: DateTimeComponents.time,
+ matchDateTimeComponents:
+ null, // Don't repeat automatically; we handle manually
);
+
+ print('Notification scheduled successfully for: $scheduledTZDateTime');
+ }
+
+ Future _scheduleNotificationForTime(
+ int dayOffset,
+ int hour,
+ int minute,
+ String title,
+ String message,
+ NotificationDetails details,
+ int notificationId,
+ ) async {
+ // Initialize and set Cairo timezone
+ tz.initializeTimeZones();
+ var cairoLocation = tz.getLocation('Africa/Cairo');
+
+ final now = tz.TZDateTime.now(cairoLocation);
+ tz.TZDateTime scheduledDate = tz.TZDateTime(
+ cairoLocation,
+ now.year,
+ now.month,
+ now.day + dayOffset, // Add offset to schedule for the next days
+ hour,
+ minute,
+ );
+
+ // If the scheduled time is in the past, move it to the next day
+ if (scheduledDate.isBefore(now)) {
+ scheduledDate = scheduledDate.add(const Duration(days: 1));
+ }
+
+ print('Current time (Cairo): $now');
+ print('Scheduling notification for: $scheduledDate');
+
+ await _flutterLocalNotificationsPlugin.zonedSchedule(
+ notificationId, // Unique ID for each notification
+ title,
+ message,
+ scheduledDate,
+ details,
+ androidScheduleMode: AndroidScheduleMode.exact,
+ uiLocalNotificationDateInterpretation:
+ UILocalNotificationDateInterpretation.absoluteTime,
+ matchDateTimeComponents:
+ null, // Don't repeat automatically; we handle 7 days manually
+ );
+
+ print('Notification scheduled successfully for: $scheduledDate');
}
}
diff --git a/lib/controller/functions/add_error.dart b/lib/controller/functions/add_error.dart
new file mode 100644
index 0000000..320a996
--- /dev/null
+++ b/lib/controller/functions/add_error.dart
@@ -0,0 +1,19 @@
+import '../../constant/box_name.dart';
+import '../../constant/links.dart';
+import '../../main.dart';
+import 'crud.dart';
+
+addError(String error, where) async {
+ CRUD().post(link: AppLink.addError, payload: {
+ 'error': error.toString(), // Example error description
+ 'userId': box.read(BoxName.driverID) ??
+ box.read(BoxName.passengerID), // Example user ID
+ 'userType': box.read(BoxName.driverID) != null
+ ? 'Driver'
+ : 'passenger', // Example user type
+ 'phone': box.read(BoxName.phone) ??
+ box.read(BoxName.phoneDriver), // Example phone number
+
+ 'device': where
+ });
+}
diff --git a/lib/controller/functions/crud.dart b/lib/controller/functions/crud.dart
index fb79448..c309e9e 100644
--- a/lib/controller/functions/crud.dart
+++ b/lib/controller/functions/crud.dart
@@ -9,6 +9,8 @@ import 'package:SEFER/env/env.dart';
import '../../constant/api_key.dart';
import '../../print.dart';
+import '../../views/widgets/elevated_btn.dart';
+import 'add_error.dart';
import 'upload_image.dart';
class CRUD {
@@ -28,8 +30,9 @@ class CRUD {
'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials.toString()))}',
},
);
- // Log.print('payload: ${payload}');
+
Log.print('response.request: ${response.request}');
+ Log.print('payload: ${payload}');
// Log.print('response.reasonPhrase: ${response.reasonPhrase}');
Log.print('response.body: ${response.body}');
@@ -43,7 +46,6 @@ class CRUD {
return jsonData['status'];
}
- // }
Future getTokenParent({
required String link,
Map? payload,
@@ -71,6 +73,73 @@ class CRUD {
}
}
+ 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 = {
+ 'Authorization': 'Bearer $accesstoken',
+ 'Content-Type': 'application/json'
+ };
+
+ var url = 'https://graph.facebook.com/v20.0/${Env.whatappID}/messages';
+ var request = http.Request('POST', Uri.parse(url));
+
+ var body = json.encode({
+ "messaging_product": "whatsapp",
+ "to": to,
+ "type": "template",
+ "template": {
+ "name": "sefer1",
+ "language": {"code": "en"},
+ "components": [
+ {
+ "type": "body",
+ "parameters": [
+ {
+ "type": "text",
+ "text": token,
+ }
+ ]
+ }
+ ]
+ }
+ });
+
+ request.body = body;
+ request.headers.addAll(headers);
+
+ try {
+ print('Sending request to $url');
+ print('Request headers: $headers');
+ print('Request body: $body');
+
+ http.StreamedResponse response = await request.send();
+
+ 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,
+ middleText: 'wait 1 minute to recive message'.tr,
+ confirm: MyElevatedButton(
+ title: 'OK'.tr,
+ onPressed: () {
+ Get.back();
+ },
+ ),
+ );
+ } else {
+ String errorBody = await response.stream.bytesToString();
+ print('Error ${response.statusCode}: ${response.reasonPhrase}');
+ print('Error body: $errorBody');
+ }
+ } catch (e) {
+ print('Exception occurred: $e');
+ }
+ }
+
Future getAgoraToken({
required String channelName,
required String uid,
@@ -215,36 +284,83 @@ class CRUD {
} else {}
}
+ // Future post({
+ // required String link,
+ // Map? payload,
+ // }) async {
+ // // String? basicAuthCredentials =
+ // // await storage.read(key: BoxName.basicAuthCredentials);
+ // var url = Uri.parse(
+ // link,
+ // );
+ // var response = await http.post(
+ // url,
+ // body: payload,
+ // headers: {
+ // "Content-Type": "application/x-www-form-urlencoded",
+ // 'Authorization':
+ // 'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials))}',
+ // },
+ // );
+ // Log.print('payload: ${payload}');
+ // Log.print('response.request: ${response.request}');
+ // Log.print('response.body: ${response.body}');
+ // var jsonData = jsonDecode(response.body);
+ // if (response.statusCode == 200) {
+ // if (jsonData['status'] == 'success') {
+ // return response.body;
+ // } else {
+ // return (jsonData['status']);
+ // }
+ // } else {
+ // return response.statusCode;
+ // }
+ // }
Future post({
required String link,
Map? payload,
}) async {
- // String? basicAuthCredentials =
- // await storage.read(key: BoxName.basicAuthCredentials);
- var url = Uri.parse(
- link,
- );
- var response = await http.post(
- url,
- body: payload,
- headers: {
- "Content-Type": "application/x-www-form-urlencoded",
- 'Authorization':
- 'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials))}',
- },
- );
- // Log.print('payload: ${payload}');
- // Log.print('response.request: ${response.request}');
- Log.print('response.body: ${response.body}');
- var jsonData = jsonDecode(response.body);
- if (response.statusCode == 200) {
- if (jsonData['status'] == 'success') {
- return response.body;
+ var url = Uri.parse(link);
+ try {
+ var response = await http.post(
+ url,
+ body: payload,
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded",
+ 'Authorization':
+ 'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials))}',
+ },
+ );
+
+ Log.print('Response.request: ${response.request}');
+ Log.print('Payload: $payload');
+ // Log.print('Response.statusCode: ${response.statusCode}');
+ Log.print('Response.body: ${response.body}');
+
+ if (response.statusCode == 200) {
+ try {
+ var jsonData = jsonDecode(response.body);
+
+ if (jsonData['status'] == 'success') {
+ return jsonData;
+ } else {
+ return jsonData['status'];
+ }
+ } catch (e) {
+ Log.print('JSON parsing error: $e');
+ addError(e.toString(), 'crud().post');
+ return 'failure'; // Return a recognizable failure string for JSON errors
+ }
} else {
- return (jsonData['status']);
+ Log.print('Non-200 response code: ${response.statusCode}');
+ addError(
+ 'Non-200 response code: ${response.statusCode}', 'crud().post');
+ return 'failure'; // Handle unexpected status codes as failures
}
- } else {
- return response.statusCode;
+ } catch (e) {
+ Log.print('HTTP request error: $e');
+ addError('HTTP request error: $e', 'crud().post');
+ return 'failure'; // Handle HTTP request errors as failures
}
}
@@ -393,6 +509,26 @@ class CRUD {
return (jsonData['status']);
}
+ Future getHereMap({
+ required String link,
+ }) async {
+ var url = Uri.parse(link);
+ try {
+ var response = await http.get(url);
+
+ if (response.statusCode == 200) {
+ // Ensure the response body is decoded as UTF-8
+ var decodedBody = utf8.decode(response.bodyBytes);
+ var data = jsonDecode(decodedBody);
+ return data;
+ } else {
+ return null;
+ }
+ } catch (e) {
+ return null;
+ }
+ }
+
Future update({
required String endpoint,
required Map data,
diff --git a/lib/controller/functions/package_info.dart b/lib/controller/functions/package_info.dart
index dc8edc2..bfcef9c 100644
--- a/lib/controller/functions/package_info.dart
+++ b/lib/controller/functions/package_info.dart
@@ -3,7 +3,6 @@ import 'dart:io';
import 'package:SEFER/constant/links.dart';
import 'package:SEFER/controller/functions/crud.dart';
import 'package:flutter/cupertino.dart';
-import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:url_launcher/url_launcher.dart';
@@ -17,7 +16,7 @@ Future checkForUpdate(BuildContext context) async {
final version = packageInfo.version;
print('currentVersion is : $currentVersion');
// Fetch the latest version from your server
- String latestVersion = await getPackageInfo();
+ String latestVersion = box.read(BoxName.package);
box.write(BoxName.packagInfo, version);
if (latestVersion.isNotEmpty && latestVersion != currentVersion) {
@@ -25,18 +24,22 @@ Future checkForUpdate(BuildContext context) async {
}
}
-Future getPackageInfo() async {
- final response = await CRUD().get(link: AppLink.packageInfo, payload: {
- "platform": Platform.isAndroid ? 'android' : 'ios',
- "appName": AppInformation.appName,
- });
-
- if (response != 'failure') {
- return jsonDecode(response)['message'][0]['version'];
- }
- return '';
+checkForBounusInvitation() {
+ if (box.read(BoxName.inviteCode) != null) {}
}
+// Future getPackageInfo() async {
+// final response = await CRUD().get(link: AppLink.packageInfo, payload: {
+// "platform": Platform.isAndroid ? 'android' : 'ios',
+// "appName": AppInformation.appName,
+// });
+
+// if (response != 'failure') {
+// return jsonDecode(response)['message'][0]['version'];
+// }
+// return '';
+// }
+
void showUpdateDialog(BuildContext context) {
final String storeUrl = Platform.isAndroid
? 'https://play.google.com/store/apps/details?id=com.mobileapp.store.ride'
@@ -65,10 +68,11 @@ void showUpdateDialog(BuildContext context) {
},
),
CupertinoDialogAction(
- child: Text('Cancel'.tr),
- onPressed: () {
- Navigator.of(context).pop();
- })
+ child: Text('Cancel'.tr),
+ onPressed: () async {
+ Navigator.of(context).pop();
+ },
+ ),
],
);
},
diff --git a/lib/controller/functions/sms_controller.dart b/lib/controller/functions/sms_controller.dart
index d63defe..09b0b63 100644
--- a/lib/controller/functions/sms_controller.dart
+++ b/lib/controller/functions/sms_controller.dart
@@ -11,6 +11,7 @@ import 'package:SEFER/views/widgets/elevated_btn.dart';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
+import '../../print.dart';
import '../auth/register_controller.dart';
import 'crud.dart';
@@ -29,12 +30,12 @@ class SmsEgyptController extends GetxController {
Future sendSmsEgypt(String phone, otp) async {
String sender = await getSender();
var body = jsonEncode({
- "username": AppInformation.appName,
+ "username": 'Sefer',
"password": AK.smsPasswordEgypt,
"message": "${AppInformation.appName} app code is $otp\ncopy it to app",
"language": box.read(BoxName.lang) == 'en' ? "e" : 'r',
"sender": sender, //"Sefer Egy",
- "receiver": "2$phone"
+ "receiver": phone
});
var res = await http.post(
diff --git a/lib/controller/functions/tts.dart b/lib/controller/functions/tts.dart
index c541c4f..5bd1b6a 100644
--- a/lib/controller/functions/tts.dart
+++ b/lib/controller/functions/tts.dart
@@ -1,49 +1,50 @@
import 'package:SEFER/constant/box_name.dart';
-import 'package:SEFER/main.dart';
import 'package:flutter/material.dart';
import 'package:flutter_tts/flutter_tts.dart';
import 'package:get/get.dart';
+import '../../main.dart';
+
class TextToSpeechController extends GetxController {
final flutterTts = FlutterTts();
- // Initialize TTS in initState
@override
void onInit() {
super.onInit();
initTts();
}
- // Dispose of TTS when controller is closed
@override
void onClose() {
+ flutterTts.stop(); // Stop any ongoing TTS
super.onClose();
- flutterTts.completionHandler;
}
- // Function to initialize TTS engine
+ // Initialize TTS engine with language check
Future initTts() async {
- String? lang =
- WidgetsBinding.instance.platformDispatcher.locale.countryCode;
- await flutterTts
- .setLanguage(box.read(BoxName.lang).toString()); //'en-US' Set language
- // await flutterTts.setLanguage('ar-SA'); //'en-US' Set language
- // await flutterTts.setLanguage(lang!); //'en-US' Set language
- await flutterTts.setSpeechRate(0.5); // Adjust speech rate
- await flutterTts.setVolume(1.0); // Set volume
+ try {
+ String langCode = box.read(BoxName.lang) ?? 'en-US';
+ bool isAvailable = await flutterTts.isLanguageAvailable(langCode);
+
+ // If language is unavailable, default to 'en-US'
+ if (!isAvailable) {
+ langCode = 'en-US';
+ }
+
+ await flutterTts.setLanguage(langCode);
+ await flutterTts.setSpeechRate(0.5); // Adjust speech rate
+ await flutterTts.setVolume(1.0); // Set volume
+ } catch (error) {
+ Get.snackbar('Error', 'Failed to initialize TTS: $error');
+ }
}
// Function to speak the given text
Future speakText(String text) async {
try {
await flutterTts.awaitSpeakCompletion(true);
- var result = await flutterTts.speak(text);
- if (result == 1) {
- // TTS operation has started
- // You can perform additional operations here, if needed
- }
+ await flutterTts.speak(text);
} catch (error) {
- // Handle error gracefully, e.g., show a message
Get.snackbar('Error', 'Failed to speak text: $error');
}
}
diff --git a/lib/controller/home/blinking_promo_controller.dart.dart b/lib/controller/home/blinking_promo_controller.dart.dart
new file mode 100644
index 0000000..df0bc82
--- /dev/null
+++ b/lib/controller/home/blinking_promo_controller.dart.dart
@@ -0,0 +1,91 @@
+import 'dart:async';
+import 'dart:convert';
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+
+import '../../constant/links.dart';
+import '../../views/widgets/elevated_btn.dart';
+import '../functions/crud.dart';
+
+class BlinkingController extends GetxController {
+ final promoFormKey = GlobalKey();
+
+ final promo = TextEditingController();
+ bool promoTaken = false;
+ void applyPromoCodeToPassenger() async {
+ //TAWJIHI
+ if (promoFormKey.currentState!.validate()) {
+ CRUD().get(link: AppLink.getPassengersPromo, payload: {
+ 'promo_code': promo.text,
+ }).then((value) {
+ if (value == 'failure') {
+ Get.defaultDialog(
+ title: 'Promo End !'.tr,
+ confirm: MyElevatedButton(
+ title: 'Back',
+ onPressed: () {
+ Get.back();
+ Get.back();
+ },
+ ));
+ }
+ var decode = jsonDecode(value);
+
+ // if (decode["status"] == "success") {
+ // var firstElement = decode["message"][0];
+ // if (double.parse(box.read(BoxName.passengerWalletTotal)) < 0) {
+ // totalPassenger = totalCostPassenger -
+ // (totalCostPassenger * int.parse(firstElement['amount']) / 100);
+ // update();
+ // } else {
+ // totalPassenger = totalCostPassenger -
+ // (totalCostPassenger * int.parse(firstElement['amount']) / 100);
+ // update();
+ // }
+
+ // totalDriver = totalDriver -
+ // (totalDriver * int.parse(firstElement['amount']) / 100);
+ // promoTaken = true;
+ // update();
+ // Get.back();
+ // }
+ });
+ }
+ }
+
+ // Reactive variable for blinking (on/off)
+ var isLightOn = false.obs;
+
+ // To animate the border color
+ var borderColor = Colors.black.obs;
+
+ Timer? _blinkingTimer;
+
+ // Method to start blinking for 5 seconds
+ void startBlinking() {
+ int count = 0;
+
+ _blinkingTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
+ // Toggle light on/off
+ isLightOn.value = !isLightOn.value;
+ borderColor.value = isLightOn.value
+ ? Colors.yellow
+ : Colors.black; // Animate border color
+
+ count++;
+
+ // Stop blinking after 5 seconds
+ if (count >= 35) {
+ timer.cancel();
+ isLightOn.value = false; // Ensure light turns off
+ borderColor.value = Colors.black; // Reset the border color
+ }
+ });
+ }
+
+ @override
+ void onClose() {
+ _blinkingTimer?.cancel();
+ super.onClose();
+ }
+}
diff --git a/lib/controller/home/contact_us_controller.dart b/lib/controller/home/contact_us_controller.dart
new file mode 100644
index 0000000..afc879f
--- /dev/null
+++ b/lib/controller/home/contact_us_controller.dart
@@ -0,0 +1,78 @@
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_font_icons/flutter_font_icons.dart';
+import 'package:get/get.dart';
+
+import '../../../constant/colors.dart';
+import '../functions/launch.dart';
+
+class ContactUsController extends GetxController {
+ final String phone1 = '+201018805430';
+ final String phone2 = '+201080182934';
+ final TimeOfDay workStartTime = const TimeOfDay(hour: 12, minute: 0);
+ final TimeOfDay workEndTime = const TimeOfDay(hour: 19, minute: 0);
+
+ bool _isWithinWorkTime(TimeOfDay now) {
+ return (now.hour > workStartTime.hour ||
+ (now.hour == workStartTime.hour &&
+ now.minute >= workStartTime.minute)) &&
+ (now.hour < workEndTime.hour ||
+ (now.hour == workEndTime.hour && now.minute <= workEndTime.minute));
+ }
+
+ void showContactDialog(BuildContext context) {
+ TimeOfDay now = TimeOfDay.now();
+
+ showCupertinoModalPopup(
+ context: context,
+ builder: (context) => CupertinoActionSheet(
+ title: Text('Contact Us'.tr),
+ message: Text('Choose a contact option'.tr),
+ actions: [
+ if (_isWithinWorkTime(now))
+ CupertinoActionSheetAction(
+ child: Text(phone1),
+ onPressed: () => makePhoneCall(
+ phone1,
+ ),
+ ),
+ if (_isWithinWorkTime(now))
+ CupertinoActionSheetAction(
+ child: Text(phone2),
+ onPressed: () => makePhoneCall(phone2),
+ ),
+ if (!_isWithinWorkTime(now))
+ CupertinoActionSheetAction(
+ child: Text(
+ 'Work time is from 12:00 - 19:00.\nYou can send a WhatsApp message or email.'
+ .tr),
+ onPressed: () => Navigator.pop(context),
+ ),
+ CupertinoActionSheetAction(
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceAround,
+ children: [
+ const Icon(
+ FontAwesome.whatsapp,
+ color: AppColor.greenColor,
+ ),
+ Text('Send WhatsApp Message'.tr),
+ ],
+ ),
+ onPressed: () =>
+ launchCommunication('whatsapp', phone1, 'Hello'.tr),
+ ),
+ CupertinoActionSheetAction(
+ child: Text('Send Email'.tr),
+ onPressed: () =>
+ launchCommunication('email', 'support@sefer.live', 'Hello'.tr),
+ ),
+ ],
+ cancelButton: CupertinoActionSheetAction(
+ child: Text('Cancel'.tr),
+ onPressed: () => Navigator.pop(context),
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/controller/home/map_passenger_controller.dart b/lib/controller/home/map_passenger_controller.dart
index 47af48b..bf3e671 100644
--- a/lib/controller/home/map_passenger_controller.dart
+++ b/lib/controller/home/map_passenger_controller.dart
@@ -1,7 +1,13 @@
import 'dart:async';
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:ui';
+import 'package:SEFER/constant/univeries_polygon.dart';
+import 'package:SEFER/controller/firebase/local_notification.dart';
+import 'package:SEFER/views/widgets/mysnakbar.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter_confetti/flutter_confetti.dart';
import 'package:vector_math/vector_math.dart' show radians, degrees;
import 'package:SEFER/controller/functions/tts.dart';
@@ -26,6 +32,7 @@ import '../../constant/links.dart';
import '../../constant/table_names.dart';
import '../../main.dart';
import '../../models/model/locations.dart';
+import '../../models/model/painter_copoun.dart';
import '../../print.dart';
import '../../views/home/map_widget.dart/car_details_widget_to_go.dart';
import '../../views/home/map_widget.dart/select_driver_mishwari.dart';
@@ -36,6 +43,7 @@ import '../functions/crud.dart';
import '../functions/launch.dart';
import '../functions/secure_storage.dart';
import '../payment/payment_controller.dart';
+import 'vip_waitting_page.dart';
class MapPassengerController extends GetxController {
bool isLoading = true;
@@ -51,6 +59,7 @@ class MapPassengerController extends GetxController {
TextEditingController whatsAppLocationText = TextEditingController();
TextEditingController messageToDriver = TextEditingController();
final sosFormKey = GlobalKey();
+ final promoFormKey = GlobalKey();
final messagesFormKey = GlobalKey();
final increaseFeeFormKey = GlobalKey();
List data = [];
@@ -137,6 +146,7 @@ class MapPassengerController extends GetxController {
double naturePrice = 0;
bool heightMenuBool = false;
String statusRide = 'wait';
+ String statusRideVip = 'wait';
bool statusRideFromStart = false;
bool isPickerShown = false;
bool isPointsPageForRider = false;
@@ -258,7 +268,7 @@ class MapPassengerController extends GetxController {
void getCurrentLocationFormString() async {
currentLocationToFormPlaces = true;
currentLocationString = 'Waiting for your location'.tr;
- getLocation();
+ await getLocation();
currentLocationString = passengerLocation.toString();
newStartPointLocation = passengerLocation;
update();
@@ -358,13 +368,46 @@ class MapPassengerController extends GetxController {
"order_id": rideId.toString(), // Convert to String
"status": 'waiting'
});
+ if (AppLink.endPoint != AppLink.seferCairoServer) {
+ CRUD().post(
+ link: "${AppLink.endPoint}/ride/driver_order/update.php",
+ payload: {
+ "order_id": rideId.toString(), // Convert to String
+ "status": 'waiting'
+ });
+ }
await CRUD().post(link: AppLink.updateRides, payload: {
"id": rideId.toString(), // Convert to String
"status": 'waiting'
});
+ if (AppLink.endPoint != AppLink.seferCairoServer) {
+ CRUD().post(
+ link: "${AppLink.endPoint}/ride/rides/update.php",
+ payload: {
+ "id": rideId.toString(), // Convert to String
+ "status": 'waiting'
+ });
+ }
+ CRUD().post(link: AppLink.updateWaitingTrip, payload: {
+ "id": rideId.toString(), // Convert to String
+ "status": 'wait'
+ });
+ if (AppLink.endPoint != AppLink.seferCairoServer) {
+ CRUD().post(
+ link:
+ "${AppLink.endPoint}/ride/notificationCaptain/updateWaitingTrip.php",
+ payload: {
+ "id": rideId.toString(), // Convert to String
+ "status": 'wait'
+ });
+ }
tick = 0;
}
- confirmRideForAllDriverAvailable();
+ await getCarsLocationByPassengerAndReloadMarker(
+ box.read(BoxName.carType), 4000);
+ // confirmRideForAllDriverAvailable();
+
+ increaseForSameRideAndDelay();
}
}
}
@@ -430,9 +473,12 @@ class MapPassengerController extends GetxController {
hintTextDestinationPoint = 'Search for your destination'.tr;
update();
} else {
- hintTextDestinationPoint = placesDestination[index]['name'];
- double lat = placesDestination[index]['geometry']['location']['lat'];
- double lng = placesDestination[index]['geometry']['location']['lng'];
+ hintTextDestinationPoint = placesDestination[index]['title'];
+ // hintTextDestinationPoint = placesDestination[index]['name'];
+ // double lat = placesDestination[index]['geometry']['location']['lat'];
+ double lat = placesDestination[index]['position']['lat'];
+ double lng = placesDestination[index]['position']['lng'];
+ // double lng = placesDestination[index]['geometry']['location']['lng'];
newMyLocation = LatLng(lat, lng);
update();
@@ -500,7 +546,7 @@ class MapPassengerController extends GetxController {
// Format the message.
String message =
- 'Hi! This is ${box.read(BoxName.name)}.\n I am using ${box.read(AppInformation.appName)} to ride with $firstName as the driver. $firstName \nis driving a $model\n with license plate $licensePlate.\n I am currently located at $passengerLocation.\n If you need to reach me, please contact the driver directly at\n\n $driverPhone.';
+ 'Hi! This is ${box.read(BoxName.name)}.\n I am using ${box.read(AppInformation.appName)} to ride with $passengerName as the driver. $passengerName \nis driving a $model\n with license plate $licensePlate.\n I am currently located at $passengerLocation.\n If you need to reach me, please contact the driver directly at\n\n $driverPhone.';
// Launch the URL to send the SMS.
launchCommunication('sms', to, message);
@@ -512,7 +558,7 @@ class MapPassengerController extends GetxController {
// Format the message.
String message =
- '${'${'Hi! This is'.tr} ${box.read(BoxName.name)}.\n${' I am using'.tr}'} ${AppInformation.appName}${' to ride with'.tr} $firstName${' as the driver.'.tr} $firstName \n${'is driving a '.tr}$model\n${' with license plate '.tr}$licensePlate.\n${' I am currently located at '.tr} https://www.google.com/maps/place/${passengerLocation.latitude},${passengerLocation.longitude}.\n${' If you need to reach me, please contact the driver directly at'.tr}\n\n $driverPhone.';
+ '${'${'Hi! This is'.tr} ${box.read(BoxName.name)}.\n${' I am using'.tr}'} ${AppInformation.appName}${' to ride with'.tr} $passengerName${' as the driver.'.tr} $passengerName \n${'is driving a '.tr}$model\n${' with license plate '.tr}$licensePlate.\n${' I am currently located at '.tr} https://www.google.com/maps/place/${passengerLocation.latitude},${passengerLocation.longitude}.\n${' If you need to reach me, please contact the driver directly at'.tr}\n\n $driverPhone.';
// Launch the URL to send the WhatsApp message.
launchCommunication('whatsapp', to, message);
@@ -544,44 +590,134 @@ class MapPassengerController extends GetxController {
return distance2;
}
+ // bool isTimerFromDriverToPassengerAfterAppliedRunning = true;
+ // int beginRideInterval = 4; // Interval in seconds for getBeginRideFromDriver
+
+ // void startTimerFromDriverToPassengerAfterApplied() async {
+ // int secondsElapsed = 0;
+
+ // while (secondsElapsed <= timeToPassengerFromDriverAfterApplied &&
+ // isTimerFromDriverToPassengerAfterAppliedRunning) {
+ // await Future.delayed(const Duration(seconds: 1));
+ // secondsElapsed++;
+
+ // progressTimerToPassengerFromDriverAfterApplied =
+ // secondsElapsed / timeToPassengerFromDriverAfterApplied;
+ // remainingTimeToPassengerFromDriverAfterApplied =
+ // timeToPassengerFromDriverAfterApplied - secondsElapsed;
+
+ // if (remainingTimeToPassengerFromDriverAfterApplied < 59) {
+ // if (rideTimerBegin == false) {
+ // rideTimerBegin = true;
+ // }
+ // }
+
+ // // Call getBeginRideFromDriver every 4 seconds
+ // if (secondsElapsed % beginRideInterval == 0) {
+ // getBeginRideFromDriver();
+ // uploadPassengerLocation();
+ // }
+
+ // int minutes =
+ // (remainingTimeToPassengerFromDriverAfterApplied / 60).floor();
+ // int seconds = remainingTimeToPassengerFromDriverAfterApplied % 60;
+ // stringRemainingTimeToPassenger =
+ // '$minutes:${seconds.toString().padLeft(2, '0')}';
+
+ // update();
+ // }
+ // }
+
+ StreamController _timerStreamController = StreamController();
+ Stream get timerStream => _timerStreamController.stream;
bool isTimerFromDriverToPassengerAfterAppliedRunning = true;
+ bool isTimerRunning = false; // Flag to track if the timer is running
int beginRideInterval = 4; // Interval in seconds for getBeginRideFromDriver
- void startTimerFromDriverToPassengerAfterApplied() async {
+ void startTimerFromDriverToPassengerAfterApplied() {
+ if (isTimerRunning) return; // Prevent duplicate streams
+ isTimerRunning = true;
+
int secondsElapsed = 0;
- while (secondsElapsed <= timeToPassengerFromDriverAfterApplied &&
- isTimerFromDriverToPassengerAfterAppliedRunning) {
- await Future.delayed(const Duration(seconds: 1));
- secondsElapsed++;
+ // Start the stream
+ Timer.periodic(const Duration(seconds: 1), (timer) {
+ if (secondsElapsed > timeToPassengerFromDriverAfterApplied ||
+ !isTimerFromDriverToPassengerAfterAppliedRunning) {
+ timer.cancel();
+ isTimerRunning = false;
+ _timerStreamController.close(); // Close the stream when done
+ return;
+ }
+ secondsElapsed++;
+ _timerStreamController.add(secondsElapsed); // Emit elapsed time
+
+ // Calculate progress and remaining time
progressTimerToPassengerFromDriverAfterApplied =
secondsElapsed / timeToPassengerFromDriverAfterApplied;
remainingTimeToPassengerFromDriverAfterApplied =
timeToPassengerFromDriverAfterApplied - secondsElapsed;
- if (remainingTimeToPassengerFromDriverAfterApplied < 59) {
- if (rideTimerBegin == false) {
- rideTimerBegin = true;
- }
- }
-
- // Call getBeginRideFromDriver every 4 seconds
- if (secondsElapsed % beginRideInterval == 0) {
- getBeginRideFromDriver();
- uploadPassengerLocation();
- }
-
+ // Update remaining time as string
int minutes =
(remainingTimeToPassengerFromDriverAfterApplied / 60).floor();
int seconds = remainingTimeToPassengerFromDriverAfterApplied % 60;
stringRemainingTimeToPassenger =
'$minutes:${seconds.toString().padLeft(2, '0')}';
- update();
- }
+ if (remainingTimeToPassengerFromDriverAfterApplied < 59 &&
+ !rideTimerBegin) {
+ rideTimerBegin = true;
+ }
+
+ // Call periodic functions
+ if (secondsElapsed % beginRideInterval == 0) {
+ getBeginRideFromDriver();
+ uploadPassengerLocation();
+ }
+
+ update(); // Notify listeners
+ });
}
+ // void startTimerFromDriverToPassengerAfterApplied() async {
+ // if (isTimerRunning) return; // Exit if timer is already running
+ // isTimerRunning = true; // Set the flag to true
+
+ // int secondsElapsed = 0;
+ // while (secondsElapsed <= timeToPassengerFromDriverAfterApplied &&
+ // isTimerFromDriverToPassengerAfterAppliedRunning) {
+ // await Future.delayed(const Duration(seconds: 1));
+ // secondsElapsed++;
+
+ // progressTimerToPassengerFromDriverAfterApplied =
+ // secondsElapsed / timeToPassengerFromDriverAfterApplied;
+ // remainingTimeToPassengerFromDriverAfterApplied =
+ // timeToPassengerFromDriverAfterApplied - secondsElapsed;
+
+ // if (remainingTimeToPassengerFromDriverAfterApplied < 59) {
+ // if (rideTimerBegin == false) {
+ // rideTimerBegin = true;
+ // }
+ // }
+
+ // // Call getBeginRideFromDriver every 4 seconds
+ // if (secondsElapsed % beginRideInterval == 0) {
+ // getBeginRideFromDriver();
+ // uploadPassengerLocation();
+ // }
+
+ // int minutes =
+ // (remainingTimeToPassengerFromDriverAfterApplied / 60).floor();
+ // int seconds = remainingTimeToPassengerFromDriverAfterApplied % 60;
+ // stringRemainingTimeToPassenger =
+ // '$minutes:${seconds.toString().padLeft(2, '0')}';
+
+ // update();
+ // }
+ // isTimerRunning = false; // Reset the flag when timer completes
+ // }
// Remove the getBeginRideFromDriverForDuration function as it's no longer needed
// Function to stop the timer
@@ -640,8 +776,16 @@ class MapPassengerController extends GetxController {
await Future.delayed(const Duration(seconds: 1));
progressTimerRideBegin = i / durationToRide;
remainingTimeTimerRideBegin = durationToRide - i;
+ if (i == (durationToRide / 4).round() && (statusRide == 'Begin')) {
+ NotificationController().showNotification("Record Your Trip".tr,
+ "You can call or record audio during this trip.".tr, 'tone1');
+ }
bool sendSOS = false;
if (speed > 100 && sendSOS == false) {
+ NotificationController().showNotification(
+ "Warning: Speeding detected!".tr,
+ 'You can call or record audio of this trip'.tr,
+ 'tone1');
Get.defaultDialog(
barrierDismissible: false,
title: "Warning: Speeding detected!".tr,
@@ -661,7 +805,7 @@ class MapPassengerController extends GetxController {
// Get trip details from GetX or relevant provider
String origin = passengerLocation.toString();
String destination = myDestination.toString();
- String driverName = firstName;
+ String driverName = passengerName;
String driverCarPlate = licensePlate;
// Add trip details to the message
@@ -707,12 +851,95 @@ class MapPassengerController extends GetxController {
// update();
}
- void tripFinishedFromDriver() async {
+ int progressTimerRideBeginVip = 0;
+ int elapsedTimeInSeconds = 0; // Timer starts from 0
+ String stringElapsedTimeRideBegin = '0:00';
+ String stringElapsedTimeRideBeginVip = '0:00';
+ bool rideInProgress = true; // To control when to stop the timer
+
+ void rideIsBeginPassengerTimerVIP() async {
+ rideInProgress = true; // Start the ride timer
+ bool sendSOS = false;
+ while (rideInProgress) {
+ await Future.delayed(const Duration(seconds: 1));
+
+ // Increment elapsed time
+ elapsedTimeInSeconds++;
+
+ // Update the time display
+ int minutes = (elapsedTimeInSeconds / 60).floor();
+ int seconds = elapsedTimeInSeconds % 60;
+ stringElapsedTimeRideBeginVip =
+ '$minutes:${seconds.toString().padLeft(2, '0')}';
+
+ // Check for speed and SOS conditions
+ if (speed > 100 && !sendSOS) {
+ Get.defaultDialog(
+ barrierDismissible: false,
+ title: "Warning: Speeding detected!".tr,
+ titleStyle: AppStyle.title,
+ content: Text(
+ "We noticed the speed is exceeding 100 km/h. Please slow down for your safety. If you feel unsafe, you can share your trip details with a contact or call the police using the red SOS button."
+ .tr,
+ style: AppStyle.title,
+ ),
+ confirm: MyElevatedButton(
+ title: "Share Trip Details".tr,
+ onPressed: () {
+ Get.back();
+ // Implement sharing trip details logic here
+ String message = "**Emergency SOS from Passenger:**\n";
+
+ // Get trip details from GetX or relevant provider
+ String origin = passengerLocation.toString();
+ String destination = myDestination.toString();
+ String driverName = passengerName;
+ String driverCarPlate = licensePlate;
+
+ // Add trip details to the message
+ message += "* ${'Origin'.tr}: $origin\n";
+ message += "* ${'Destination'.tr}: $destination\n";
+ message += "* ${'Driver Name'.tr}: $driverName\n";
+ message += "* ${'Driver Car Plate'.tr}: $driverCarPlate\n\n";
+ message += "* ${'Driver Phone'.tr}: $driverPhone\n\n";
+
+ // Add current location
+ message +=
+ "${'Current Location'.tr}:https://www.google.com/maps/place/${passengerLocation.latitude},${passengerLocation.longitude} \n";
+
+ // Append a call to action
+ message += "Please help! Contact me as soon as possible.".tr;
+
+ // Launch WhatsApp communication
+ launchCommunication(
+ 'whatsapp', box.read(BoxName.sosPhonePassenger), message);
+ sendSOS = true;
+ },
+ kolor: AppColor.redColor,
+ ),
+ cancel: MyElevatedButton(
+ title: "Cancel".tr,
+ onPressed: () {
+ Get.back();
+ },
+ kolor: AppColor.greenColor,
+ ),
+ );
+ }
+
+ // Update the UI
+ update();
+ }
+ }
+
+ void tripFinishedFromDriver() {
isRideFinished = true;
rideTimerBegin = false;
+ statusRideVip = 'Finished';
box.write(BoxName.arrivalTime, '');
remainingTimeTimerRideBegin = 0;
box.write(BoxName.passengerWalletTotal, '0');
+ update();
if (box.read(BoxName.parentTripSelected) == true) {
FirebaseMessagesController().sendNotificationToPassengerToken(
"Finish Monitor".tr,
@@ -724,34 +951,116 @@ class MapPassengerController extends GetxController {
box.write(BoxName.parentTripSelected, false);
box.remove(BoxName.tokenParent);
}
- update();
}
- void getBeginRideFromDriver() async {
- try {
- var res = await CRUD()
- .get(link: AppLink.getRideStatusBegin, payload: {'ride_id': rideId});
- if (res != 'failure') {
- var decode = jsonDecode(res);
+ // bool isBeginRideFromDriver = false;
+ // void getBeginRideFromDriver() async {
+ // try {
+ // if (isBeginRideFromDriver) return; // Prevent duplicate streams
+ // isBeginRideFromDriver = true;
+ // var res = await CRUD()
+ // .get(link: AppLink.getRideStatusBegin, payload: {'ride_id': rideId});
+ // if (res != 'failure') {
+ // var decode = jsonDecode(res);
- if (decode['data']['status'] == 'Begin') {
- timeToPassengerFromDriverAfterApplied = 0;
- remainingTime = 0;
- remainingTimeToPassengerFromDriverAfterApplied = 0;
- remainingTimeDriverWaitPassenger5Minute = 0;
- rideTimerBegin = true;
- statusRide = 'Begin';
- isDriverInPassengerWay = false;
- isDriverArrivePassenger = false;
- update();
- // isCancelRidePageShown = true;
- rideIsBeginPassengerTimer();
- runWhenRideIsBegin();
+ // // if (decode['data']['status'] != 'Apply') {
+ // if (decode['data']['status'] == 'Begin') {
+ // timeToPassengerFromDriverAfterApplied = 0;
+ // remainingTime = 0;
+ // remainingTimeToPassengerFromDriverAfterApplied = 0;
+ // remainingTimeDriverWaitPassenger5Minute = 0;
+ // rideTimerBegin = true;
+ // statusRide = 'Begin';
+ // isDriverInPassengerWay = false;
+ // isDriverArrivePassenger = false;
+ // update();
+ // // isCancelRidePageShown = true;
+ // rideIsBeginPassengerTimer();
+ // runWhenRideIsBegin();
+ // } else {}
+ // }
+ // } catch (e) {
+ // // Handle the error or perform any necessary actions
+ // }
+ // }
+
+ StreamController _beginRideStreamController =
+ StreamController.broadcast();
+ Stream get beginRideStream => _beginRideStreamController.stream;
+
+ bool isBeginRideFromDriverRunning = false;
+
+ void getBeginRideFromDriver() {
+ if (isBeginRideFromDriverRunning) return; // Prevent duplicate streams
+ isBeginRideFromDriverRunning = true;
+
+ Timer.periodic(const Duration(seconds: 1), (timer) async {
+ try {
+ var res = await CRUD().get(
+ link: AppLink.getRideStatusBegin, payload: {'ride_id': rideId});
+ print(res);
+ print('1002');
+ if (res != 'failure') {
+ var decode = jsonDecode(res);
+ _beginRideStreamController
+ .add(decode['data']['status']); // Emit the status
+
+ if (decode['data']['status'] == 'Begin') {
+ // Stop the periodic check
+ timer.cancel();
+ isBeginRideFromDriverRunning = false;
+
+ timeToPassengerFromDriverAfterApplied = 0;
+ remainingTime = 0;
+ remainingTimeToPassengerFromDriverAfterApplied = 0;
+ remainingTimeDriverWaitPassenger5Minute = 0;
+ rideTimerBegin = true;
+ statusRide = 'Begin';
+ isDriverInPassengerWay = false;
+ isDriverArrivePassenger = false;
+ update();
+
+ // Trigger additional actions
+ rideIsBeginPassengerTimer();
+ runWhenRideIsBegin();
+ NotificationController().showNotification(
+ 'Trip is begin'.tr,
+ 'The trip has started! Feel free to contact emergency numbers, share your trip, or activate voice recording for the journey'
+ .tr,
+ 'ding');
+ }
}
+ } catch (e) {
+ // Handle errors
+ _beginRideStreamController.addError(e);
}
- } catch (e) {
- // Handle the error or perform any necessary actions
- }
+ });
+ }
+
+// Call this method to listen to the stream
+ void listenToBeginRideStream() {
+ beginRideStream.listen((status) {
+ print("Ride status: $status");
+ // Perform additional actions based on the status
+ }, onError: (error) {
+ print("Error in Begin Ride Stream: $error");
+ });
+ }
+
+ begiVIPTripFromPassenger() async {
+ timeToPassengerFromDriverAfterApplied = 0;
+ remainingTime = 0;
+ isBottomSheetShown = false;
+ remainingTimeToPassengerFromDriverAfterApplied = 0;
+ remainingTimeDriverWaitPassenger5Minute = 0;
+ rideTimerBegin = true;
+ statusRideVip = 'Begin';
+ isDriverInPassengerWay = false;
+ isDriverArrivePassenger = false;
+ update();
+ // isCancelRidePageShown = true;
+ rideIsBeginPassengerTimerVIP();
+ runWhenRideIsBegin();
}
Map rideStatusFromStartApp = {};
@@ -760,6 +1069,8 @@ class MapPassengerController extends GetxController {
var res = await CRUD().get(
link: AppLink.getRideStatusFromStartApp,
payload: {'passenger_id': box.read(BoxName.passengerID)});
+ print(res);
+ print('1070');
if (res == 'failure') {
print(
"No rides found for the given passenger ID within the last hour.");
@@ -768,7 +1079,7 @@ class MapPassengerController extends GetxController {
if (rideStatusFromStartApp['data']['status'] == 'Begin') {
statusRide = 'Begin';
driverId = rideStatusFromStartApp['data']['driver_id'];
- firstName = rideStatusFromStartApp['data']['driverName'];
+ passengerName = rideStatusFromStartApp['data']['driverName'];
driverRate = rideStatusFromStartApp['data']['rateDriver'].toString();
statusRideFromStart = true;
// DateTime endTime =
@@ -921,7 +1232,7 @@ class MapPassengerController extends GetxController {
// Extract the URL part from the link by finding the first occurrence of "http"
int urlStartIndex = link.indexOf(RegExp(r'https?://'));
if (urlStartIndex == -1) {
- throw FormatException('No URL found in the provided link.');
+ throw const FormatException('No URL found in the provided link.');
}
// Extract the URL and clean it
@@ -1010,320 +1321,438 @@ class MapPassengerController extends GetxController {
int currentTimeSearchingCaptainWindow = 0;
late String driverPhone = '';
late String driverRate = '';
- late String firstName = '';
+ late String passengerName = '';
late String carColor = '';
+ late String colorHex = '';
late String carYear = '';
late String model = '';
late String make = '';
late String licensePlate = '';
- confirmRideForFirstDriver() async {
- startCarLocationSearch(box.read(BoxName.carType));
- // await getCarsLocationByPassengerAndReloadMarker(
- // box.read(BoxName.carType), 7000);
- await getNearestDriverByPassengerLocationAPIGOOGLE();
- Log.print('dataCarsLocationByPassenger: ${dataCarsLocationByPassenger}');
- if (dataCarsLocationByPassenger != 'failure' ||
- dataCarsLocationByPassenger != null) {
- driverToken =
- dataCarsLocationByPassenger['message'][carsOrder]['token'].toString();
- driverPhone =
- dataCarsLocationByPassenger['message'][carsOrder]['phone'].toString();
- firstName = dataCarsLocationByPassenger['message'][carsOrder]
- ['first_name'] // driverName
- .toString();
- carColor =
- dataCarsLocationByPassenger['message'][carsOrder]['color'].toString();
- driverRate = dataCarsLocationByPassenger['message'][carsOrder]
- ['ratingDriver']
- .toString();
- carYear =
- dataCarsLocationByPassenger['message'][carsOrder]['year'].toString();
- model =
- '${dataCarsLocationByPassenger['message'][carsOrder]['model']} - ${dataCarsLocationByPassenger['message'][carsOrder]['make']}';
- licensePlate = dataCarsLocationByPassenger['message'][carsOrder]
- ['car_plate']
- .toString();
- PaymentController paymentController = Get.find();
- rideConfirm = true;
- shouldFetch = true;
- isBottomSheetShown = false;
- timeToPassengerFromDriverAfterApplied =
- durationToPassenger; //60 todo durationToPassenger;/
- isDriversTokensSend = false;
+ String driverOrderStatus = 'yet';
+ bool isDriversTokensSend = false;
- update();
- await CRUD().post(link: AppLink.addRides, 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['message'][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) {
- // List body = [
- rideId = jsonDecode(value)['message'];
- List body = [
+ Set notifiedDrivers = {};
+
+ addRideToNotificationDriverAvailable() async {
+ await CRUD().post(link: AppLink.addWaitingRide, payload: {
+ 'id': rideId.toString(),
+ 'start_location':
'${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
+ 'end_location':
'${data[0]["end_location"]['lat']},${data[0]["end_location"]['lng']}',
- totalPassenger.toStringAsFixed(2),
- totalDriver.toStringAsFixed(2),
- durationToRide.toString(),
- distance.toStringAsFixed(2),
- dataCarsLocationByPassenger['message'][carsOrder]['driver_id']
- .toString(),
- box.read(BoxName.passengerID).toString(),
- box.read(BoxName.name).toString(),
- box.read(BoxName.tokenFCM).toString(),
- box.read(BoxName.phone).toString(),
- durationByPassenger.toString(),
- distanceByPassenger.toString(),
- paymentController.isWalletChecked.toString(),
- dataCarsLocationByPassenger['message'][carsOrder]['token'].toString(),
- durationToPassenger.toString(),
- rideId,
- rideTimerBegin.toString(),
- dataCarsLocationByPassenger['message'][carsOrder]['driver_id']
- .toString(),
- durationToRide.toString(),
- Get.find().wayPoints.length > 1
- ? 'haveSteps'
- : 'startEnd',
- placesCoordinate[0],
- placesCoordinate[1],
- placesCoordinate[2],
- placesCoordinate[3],
- placesCoordinate[4],
- costForDriver.toStringAsFixed(2),
- double.parse(box.read(BoxName.passengerWalletTotal)) < 0
- ? double.parse(box.read(BoxName.passengerWalletTotal))
- .toStringAsFixed(2)
- : '0',
- box.read(BoxName.email).toString(),
- startNameAddress,
- endNameAddress,
- box.read(BoxName.carType),
- kazan.toStringAsFixed(0),
- passengerRate.toStringAsFixed(2),
- ];
- Log.print('body: ${body}');
- FirebaseMessagesController().sendNotificationToDriverMAP(
- 'Order'.tr,
- 'from: $startNameAddress\nto: $startNameAddress\ndistanceFromMe: $distanceByPassenger\nDistance :$distance\nPrice ; $totalPassenger',
- // jsonDecode(value)['message'].toString(),
- dataCarsLocationByPassenger['message'][carsOrder]['token']
- .toString(),
- body,
- 'order.wav'
+ "date": DateTime.now().toString(),
+ "time": DateTime.now().toString(),
+ "price": totalPassenger.toStringAsFixed(2),
+ 'passenger_id': box.read(BoxName.passengerID).toString(),
+ 'status': 'waiting',
+ 'carType': box.read(BoxName.carType),
+ 'passengerRate': passengerRate.toStringAsFixed(2),
+ 'price_for_passenger': totalME.toStringAsFixed(2),
+ 'distance': distance.toStringAsFixed(1),
+ 'duration': duration.toStringAsFixed(1),
+ });
- // polylineCoordinates.toString()
- );
- Log.print(
- 'body: ${dataCarsLocationByPassenger['message'][carsOrder]['token']}');
- });
+ if (AppLink.endPoint != AppLink.seferCairoServer) {
CRUD().post(
- link: '${AppLink.seferAlexandriaServer}/ride/rides/add.php',
+ link: '${AppLink.endPoint}/notificationCaptain/addWaitingRide.php',
payload: {
- "start_location": //'${data[0]['start_address']}',
+ 'id': rideId.toString(),
+ 'start_location':
'${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
- "end_location": //'${data[0]['end_address']}',
+ '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['message'][carsOrder]
- ['driver_id']
- .toString(),
- "status": "waiting",
+ 'passenger_id': box.read(BoxName.passengerID).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(),
+ 'passengerRate': passengerRate.toStringAsFixed(2),
+ 'price_for_passenger': totalME.toStringAsFixed(2),
+ 'distance': distance.toStringAsFixed(1),
+ 'duration': duration.toStringAsFixed(0),
});
- CRUD().post(
- link: '${AppLink.seferGizaServer}/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['message'][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(),
- });
-
- delayAndFetchRideStatus(rideId);
- if (shouldFetch == false) {
- startTimer();
- update();
- }
- update();
- } else {
- Get.defaultDialog(
- title: 'No Car or Driver Found in your area.'.tr,
- titleStyle: AppStyle.title,
- middleText: 'Please Try anther time '.tr,
- middleTextStyle: AppStyle.title.copyWith(color: AppColor.yellowColor),
- confirm: MyElevatedButton(
- title: 'Ok'.tr,
- onPressed: () {
- Get.back();
- isSearchingWindow = false;
- cancelRide();
- update();
- }));
}
}
- bool isDriversTokensSend = false;
- confirmRideForAllDriverAvailable() async {
- await getCarsLocationByPassengerAndReloadMarker(
- box.read(BoxName.carType), 7000);
- if (dataCarsLocationByPassenger != 'failure') {
- driversToken.remove(driverToken);
- PaymentController paymentController = Get.find();
- rideConfirm = true;
- shouldFetch = true;
- isBottomSheetShown = false;
- timeToPassengerFromDriverAfterApplied = 60;
+ // Future confirmRideForAllDriverAvailable1() async {
+ // // Try to fetch car locations up to 4 times with a 2-second delay
+ // bool driversFound = false;
+ // for (int attempt = 0; attempt < 8; attempt++) {
+ // await getCarsLocationByPassengerAndReloadMarker(
+ // box.read(BoxName.carType), attempt > 5 ? 4500 : 3000);
- List body = [
- '${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
- '${data[0]["end_location"]['lat']},${data[0]["end_location"]['lng']}',
- totalPassenger.toStringAsFixed(2),
- totalDriver.toStringAsFixed(2),
- durationToRide.toString(),
- distance.toStringAsFixed(2),
- dataCarsLocationByPassenger['message'][carsOrder]['driver_id']
- .toString(),
- box.read(BoxName.passengerID).toString(),
- box.read(BoxName.name).toString(),
- box.read(BoxName.tokenFCM).toString(),
- box.read(BoxName.phone).toString(),
- durationByPassenger.toString(),
- distanceByPassenger.toString(),
- paymentController.isWalletChecked.toString(),
- dataCarsLocationByPassenger['message'][carsOrder]['token'].toString(),
- durationToPassenger.toString(),
- rideId,
- rideTimerBegin.toString(),
- dataCarsLocationByPassenger['message'][carsOrder]['driver_id']
- .toString(),
- durationToRide.toString(),
- Get.find().wayPoints.length > 1
- ? 'haveSteps'
- : 'startEnd',
- placesCoordinate[0],
- placesCoordinate[1],
- placesCoordinate[2],
- placesCoordinate[3],
- placesCoordinate[4],
- costForDriver.toStringAsFixed(2),
- double.parse(box.read(BoxName.passengerWalletTotal)) < 0
- ? double.parse(box.read(BoxName.passengerWalletTotal))
- .toStringAsFixed(2)
- : '0',
- box.read(BoxName.email).toString(),
- startNameAddress,
- endNameAddress,
- box.read(BoxName.carType),
- kazan.toStringAsFixed(0),
- passengerRate.toStringAsFixed(2),
- ];
- Log.print('body: ${body}');
- for (var i = 1; i < driversToken.length; i++) {
- FirebaseMessagesController().sendNotificationToDriverMapPolyline(
- 'OrderSpeed',
- rideId.toString(),
- driversToken[i],
- body,
- polylineCoordinates.toString());
- }
+ // // Check if dataCarsLocationByPassenger is valid and contains drivers
+ // if (dataCarsLocationByPassenger != 'failure' &&
+ // dataCarsLocationByPassenger != null &&
+ // dataCarsLocationByPassenger.containsKey('data') &&
+ // dataCarsLocationByPassenger['message'] != null) {
+ // driversFound = true;
+ // break; // Exit loop if drivers are found
+ // }
- (rideId);
+ // // Wait 2 seconds before next attempt
+ // await Future.delayed(const Duration(seconds: 2));
+ // }
- update();
- } 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());
- });
- }
+ // // 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();
+ // 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['message'][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(
+ // box.read(BoxName.carType), 3000);
+ // if (dataCarsLocationByPassenger != null &&
+ // dataCarsLocationByPassenger.containsKey('data') &&
+ // dataCarsLocationByPassenger['message'] != null) {
+ // for (var driverData in dataCarsLocationByPassenger['message']) {
+ // String driverId = driverData['driver_id'].toString();
+ // if (!notifiedDrivers.contains(driverId)) {
+ // notifiedDrivers.add(driverId);
+ // List body = [
+ // '${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
+ // '${data[0]["end_location"]['lat']},${data[0]["end_location"]['lng']}',
+ // totalPassenger.toStringAsFixed(2),
+ // totalDriver.toStringAsFixed(2),
+ // durationToRide.toString(),
+ // distance.toStringAsFixed(2),
+ // driverId.toString(),
+ // box.read(BoxName.passengerID).toString(),
+ // box.read(BoxName.name).toString(),
+ // box.read(BoxName.tokenFCM).toString(),
+ // box.read(BoxName.phone).toString(),
+ // durationByPassenger.toString(),
+ // distanceByPassenger.toString(),
+ // paymentController.isWalletChecked.toString(),
+ // driverData['token'].toString(),
+ // durationToPassenger.toString(),
+ // rideId.toString(),
+ // rideTimerBegin.toString(),
+ // driverId.toString(),
+ // durationToRide.toString(),
+ // Get.find().wayPoints.length > 1
+ // ? 'haveSteps'
+ // : 'startEnd',
+ // placesCoordinate[0],
+ // placesCoordinate[1],
+ // placesCoordinate[2],
+ // placesCoordinate[3],
+ // placesCoordinate[4],
+ // costForDriver.toStringAsFixed(2),
+ // (double.parse(box.read(BoxName.passengerWalletTotal)) < 0
+ // ? double.parse(box.read(BoxName.passengerWalletTotal))
+ // .toStringAsFixed(2)
+ // : '0'),
+ // box.read(BoxName.email).toString(),
+ // data[0]['start_address'],
+ // data[0]['end_address'],
+ // box.read(BoxName.carType),
+ // kazan.toStringAsFixed(0),
+ // passengerRate.toStringAsFixed(2),
+ // ];
+ // Log.print('body: ${body}');
+ // FirebaseMessagesController().sendNotificationToDriverMAP(
+ // 'OrderSpeed',
+ // rideId,
+ // driverData['token'].toString(),
+ // body,
+ // 'order.wav',
+ // );
+ // }
+ // }
+ // }
+ // });
+ // });
+
+ // // If an additional endpoint is available, post data there as well
+ // if (AppLink.endPoint != AppLink.seferCairoServer) {
+ // 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['message'][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();
+ // }
+
+ increaseForSameRideAndDelay() async {
+ reSearchAfterCanceledFromDriver();
+ // bool driversFound = false;
+ // for (int attempt = 0; attempt < 8; attempt++) {
+ // await getCarsLocationByPassengerAndReloadMarker(
+ // box.read(BoxName.carType), 4500);
+
+ // // Check if dataCarsLocationByPassenger is valid and contains drivers
+ // if (dataCarsLocationByPassenger != 'failure' &&
+ // dataCarsLocationByPassenger != null &&
+ // dataCarsLocationByPassenger.containsKey('message') &&
+ // dataCarsLocationByPassenger['message'] != null) {
+ // driversFound = true;
+ // break; // Exit loop if drivers are found
+ // }
+
+ // // Wait 2 seconds before next attempt
+ // await Future.delayed(const Duration(seconds: 2));
+ // }
+
+ // // 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;
+ // }
+ // PaymentController paymentController = Get.find();
+ // rideConfirm = true;
+ // shouldFetch = true;
+ // isBottomSheetShown = false;
+ // timeToPassengerFromDriverAfterApplied = 60;
+ // // confirmRideForAllDriverAvailable();
+ // for (var i = 0; i < dataCarsLocationByPassenger['message'].length; i++) {
+ // List body = [
+ // '${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
+ // '${data[0]["end_location"]['lat']},${data[0]["end_location"]['lng']}',
+ // totalPassenger.toStringAsFixed(2),
+ // totalDriver.toStringAsFixed(2),
+ // durationToRide.toString(),
+ // distance.toStringAsFixed(2),
+ // dataCarsLocationByPassenger['message'][i]['driver_id'].toString(),
+ // box.read(BoxName.passengerID).toString(),
+ // box.read(BoxName.name).toString(),
+ // box.read(BoxName.tokenFCM).toString(),
+ // box.read(BoxName.phone).toString(),
+ // durationByPassenger.toString(),
+ // distanceByPassenger.toString(),
+ // paymentController.isWalletChecked.toString(),
+ // dataCarsLocationByPassenger['message'][i]['token'].toString(),
+ // durationToPassenger.toString(),
+ // rideId.toString(),
+ // rideTimerBegin.toString(),
+ // dataCarsLocationByPassenger['message'][i]['driver_id'].toString(),
+ // durationToRide.toString(),
+ // Get.find().wayPoints.length > 1
+ // ? 'haveSteps'
+ // : 'startEnd',
+ // placesCoordinate[0],
+ // placesCoordinate[1],
+ // placesCoordinate[2],
+ // placesCoordinate[3],
+ // placesCoordinate[4],
+ // costForDriver.toStringAsFixed(2),
+ // double.parse(box.read(BoxName.passengerWalletTotal)) < 0
+ // ? double.parse(box.read(BoxName.passengerWalletTotal))
+ // .toStringAsFixed(2)
+ // : '0',
+ // box.read(BoxName.email).toString(),
+ // data[0]['start_address'],
+ // data[0]['end_address'],
+ // box.read(BoxName.carType),
+ // kazan.toStringAsFixed(0),
+ // passengerRate.toStringAsFixed(2),
+ // ];
+ // // Log.print('body: ${body}');
+
+ // FirebaseMessagesController().sendNotificationToDriverMAP(
+ // 'OrderSpeed',
+ // rideId.toString(),
+ // dataCarsLocationByPassenger['message'][i]['token'].toString(),
+ // body,
+ // 'order.wav');
+ // }
}
int tick = 0; // Move tick outside the function to maintain its state
- void delayAndFetchRideStatus(String rideId) {
- Timer.periodic(const Duration(seconds: 1), (timer) async {
- if (shouldFetch) {
- if (remainingTimeToPassengerFromDriverAfterApplied > 0) {
- String res = await getRideStatus(rideId);
+ // void delayAndFetchRideStatus(String rideId, carType) {
+ // Timer.periodic(const Duration(seconds: 1), (timer) async {
+ // if (shouldFetch) {
+ // if (remainingTimeToPassengerFromDriverAfterApplied > 0) {
+ // String res = await getRideStatus(rideId);
- Log.print('tick: $tick');
-
- if (res.toString() == 'waiting' && tick >= 15) {
- timer.cancel(); // Stop the current timer
- showAndResearchForCaptain();
- // delayAndFetchRideStatusForAllDriverAvailable(rideId);
- } else if (res.toString() == 'Apply') {
- // todo play sound
- Get.find()
- .playSoundFromAssets('assets/start.wav');
- timer.cancel(); // Stop the current timer
- shouldFetch = false; // Stop further fetches
- statusRide = 'Apply';
- rideConfirm = false;
- isSearchingWindow = false;
- update();
- startTimerFromDriverToPassengerAfterApplied();
- } else if (res.toString() == 'Refused') {
- statusRide = 'Refused';
- if (isDriversTokensSend == false) {
- confirmRideForAllDriverAvailable();
- isDriversTokensSend = true;
- } // Start 15-second timer
- }
- //else if (isDriversTokensSend == false) {
- // No need to recall delayAndFetchRideStatus as Timer.periodic is already running
- update();
- // }
- tick++;
- } else {
- timer.cancel();
- // Stop the timer if remainingTimeToPassengerFromDriverAfterApplied <= 0
- }
- } else {
- timer.cancel(); // Stop the timer if shouldFetch is false
- }
- });
- }
+ // Log.print('tick: $tick');
+ // String rideStatusDelayed = res.toString();
+ // if ((rideStatusDelayed == 'waiting' ||
+ // rideStatusDelayed == 'Refused') &&
+ // tick >= 15) {
+ // timer.cancel(); // Stop the current timer
+ // showAndResearchForCaptain();
+ // //TODO add to wait
+ // await getCarsLocationByPassengerAndReloadMarker(carType, 3000);
+ // // await getNearestDriverByPassengerLocationAPIGOOGLE();
+ // // getCarForFirstConfirm(carType);
+ // confirmRideForAllDriverAvailable();
+ // // delayAndFetchRideStatusForAllDriverAvailable(rideId);
+ // } else if (rideStatusDelayed == 'Apply' || statusRide == 'Apply') {
+ // Log.print('rideStatusDelayed == Apply: $rideStatusDelayed');
+ // // todo play sound
+ // Get.find()
+ // .playSoundFromAssets('assets/start.wav');
+ // timer.cancel(); // Stop the current timer
+ // await getUpdatedRideForDriverApply(rideId);
+ // shouldFetch = false; // Stop further fetches
+ // statusRide = 'Apply';
+ // rideConfirm = false;
+ // isSearchingWindow = false;
+ // update();
+ // startTimerFromDriverToPassengerAfterApplied();
+ // if (box.read(BoxName.carType) == 'Speed' ||
+ // box.read(BoxName.carType) == 'Awfar Car') {
+ // NotificationController().showNotification(
+ // 'The captain is responsible for the route.'.tr,
+ // 'This price is fixed even if the route changes for the driver.'
+ // .tr,
+ // 'ding');
+ // } else if (box.read(BoxName.carType) == 'Comfort' ||
+ // box.read(BoxName.carType) == 'Lady') {
+ // NotificationController().showNotification('Attention'.tr,
+ // 'The price may increase if the route changes.'.tr, 'ding');
+ // }
+ // } else if (rideStatusDelayed == 'Refused') {
+ // statusRide = 'Refused';
+ // if (isDriversTokensSend == false) {
+ // confirmRideForAllDriverAvailable();
+ // isDriversTokensSend = true;
+ // } // Start 15-second timer
+ // }
+ // //else if (isDriversTokensSend == false) {
+ // // No need to recall delayAndFetchRideStatus as Timer.periodic is already running
+ // update();
+ // // }
+ // if (tick < 19) {
+ // tick++;
+ // } else {
+ // timer.cancel();
+ // // Stop the timer if remainingTimeToPassengerFromDriverAfterApplied <= 0
+ // }
+ // } else {
+ // timer.cancel();
+ // // Stop the timer if remainingTimeToPassengerFromDriverAfterApplied <= 0
+ // }
+ // } else {
+ // timer.cancel(); // Stop the timer if shouldFetch is false
+ // }
+ // });
+ // }
showAndResearchForCaptain() {
Get.snackbar(
@@ -1333,128 +1762,368 @@ class MapPassengerController extends GetxController {
duration: const Duration(seconds: 5),
backgroundColor: AppColor.yellowColor,
);
+ isSearchingWindow == true;
+ update();
}
- void delayAndFetchRideStatusForAllDriverAvailable(String rideId) async {
+ String driversStatusForSearchWindow = '';
+ Future confirmRideForAllDriverAvailable() async {
+ bool driversFound = false;
+ const maxAttempts = 8;
+ const attemptDelay = Duration(seconds: 3);
+
+ for (int attempt = 0; attempt < maxAttempts; attempt++) {
+ final reloadDuration = attempt > 5 ? 4500 : 3000;
+ await getCarsLocationByPassengerAndReloadMarker(
+ box.read(BoxName.carType), reloadDuration);
+ // await getNearestDriverByPassengerLocation();
+ driversStatusForSearchWindow = 'We are search for nearst driver'.tr;
+ if (isDriversDataValid()) {
+ driversFound = true;
+ break;
+ }
+
+ await Future.delayed(attemptDelay);
+ }
+
+ if (!driversFound) {
+ showNoDriversDialog();
+ return;
+ }
+ driversStatusForSearchWindow = 'Your order is being prepared'.tr;
+ Log.print('driversStatusForSearchWindow: ${driversStatusForSearchWindow}');
+ update();
+ await postRideDetailsToServer();
+ driversStatusForSearchWindow = 'Your order sent to drivers'.tr;
+ await notifyAvailableDrivers();
+
+ driversStatusForSearchWindow = 'The drivers are reviewing your request'.tr;
+ Log.print('driversStatusForSearchWindow: ${driversStatusForSearchWindow}');
+ update();
+ delayAndFetchRideStatusForAllDriverAvailable(rideId);
+ update();
+ }
+
+ Future updateConfirmRideForAllDriverAvailable() async {
+ bool driversFound = false;
+ const maxAttempts = 8;
+ const attemptDelay = Duration(seconds: 3);
+
+ for (int attempt = 0; attempt < maxAttempts; attempt++) {
+ final reloadDuration = attempt > 5 ? 4500 : 3000;
+ await getCarsLocationByPassengerAndReloadMarker(
+ box.read(BoxName.carType), reloadDuration);
+ // await getNearestDriverByPassengerLocation();
+
+ if (isDriversDataValid()) {
+ driversFound = true;
+ break;
+ }
+
+ await Future.delayed(attemptDelay);
+ }
+
+ if (!driversFound) {
+ showNoDriversDialog();
+ return;
+ }
+
+ // await postRideDetailsToServer();
+ await notifyAvailableDrivers();
+ delayAndFetchRideStatusForAllDriverAvailable(rideId);
+ update();
+ }
+
+ bool isDriversDataValid() {
+ return dataCarsLocationByPassenger != 'failure' &&
+ dataCarsLocationByPassenger != null &&
+ dataCarsLocationByPassenger.containsKey('message') &&
+ dataCarsLocationByPassenger['message'] != null;
+ }
+
+ void showNoDriversDialog() {
+ 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,
+ );
+ }
+
+ Future postRideDetailsToServer() async {
+ final paymentController = Get.find();
+ final payload = constructRidePayload(paymentController);
+
+ try {
+ final response = await CRUD().post(
+ link: "${AppLink.seferCairoServer}/ride/rides/add.php",
+ payload: payload);
+ if (response is String) {
+ final parsedValue = jsonDecode(response);
+ rideId = parsedValue['message'];
+ } else if (response is Map) {
+ rideId = response['message'];
+ } else {
+ Log.print('Unexpected response type: ${response.runtimeType}');
+ }
+ } catch (e) {
+ Log.print('Error posting ride details: $e');
+ }
+ }
+
+ Map constructRidePayload(
+ PaymentController paymentController) {
+ final startLocation =
+ '${data[0]['start_location']['lat']},${data[0]['start_location']['lng']}';
+ final endLocation =
+ '${data[0]['end_location']['lat']},${data[0]['end_location']['lng']}';
+
+ return {
+ "start_location": startLocation,
+ "end_location": endLocation,
+ "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['message'][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(),
+ };
+ }
+
+ Future notifyAvailableDrivers() async {
+ int iteration = 0;
+ const maxIterations = 5;
+ const iterationDelay = Duration(seconds: 2);
+
+ while (iteration < maxIterations) {
+ await Future.delayed(iterationDelay);
+ await getCarsLocationByPassengerAndReloadMarker(
+ box.read(BoxName.carType), 3000);
+
+ if (dataCarsLocationByPassenger != null &&
+ dataCarsLocationByPassenger.containsKey('message') &&
+ dataCarsLocationByPassenger['message'] != null) {
+ for (var driverData in dataCarsLocationByPassenger['message']) {
+ String driverId = driverData['driver_id'].toString();
+ if (!notifiedDrivers.contains(driverId)) {
+ notifiedDrivers.add(driverId);
+ double driverLat = double.parse(driverData['latitude']);
+ double driverLng = double.parse(driverData['longitude']);
+ double distanceToDriverInMeters = Geolocator.distanceBetween(
+ passengerLocation.latitude,
+ passengerLocation.longitude,
+ driverLat,
+ driverLng,
+ );
+
+ double distanceToDriverInKm = distanceToDriverInMeters *
+ 1.25 / //to approximate to stright distance
+ 1000;
+ double durationToDriverInHours =
+ distanceToDriverInKm / 25; // 25 km/h as default speed
+ double durationToDriverInSeconds = durationToDriverInHours * 3600;
+ durationToPassenger = durationToDriverInSeconds.toInt();
+ distanceByPassenger =
+ (distanceToDriverInMeters * 1.25).toStringAsFixed(0);
+ Future.delayed(const Duration(microseconds: 10));
+ final body = constructNotificationBody(driverData);
+ // Log.print('body:ww ${body}');
+ FirebaseMessagesController().sendNotificationToDriverMAP(
+ 'OrderSpeed',
+ rideId,
+ driverData['token'].toString(),
+ body,
+ 'order.wav');
+ }
+ }
+ }
+ iteration++;
+ }
+ }
+
+ List constructNotificationBody(var driverData) {
+ final paymentController = Get.find();
+ return [
+ '${data[0]['start_location']['lat']},${data[0]['start_location']['lng']}',
+ '${data[0]['end_location']['lat']},${data[0]['end_location']['lng']}',
+ totalPassenger.toStringAsFixed(2),
+ totalDriver.toStringAsFixed(2),
+ durationToRide.toString(),
+ distance.toStringAsFixed(2),
+ driverData['driver_id'].toString(),
+ box.read(BoxName.passengerID).toString(),
+ box.read(BoxName.name).toString(),
+ box.read(BoxName.tokenFCM).toString(),
+ box.read(BoxName.phone).toString(),
+ durationToPassenger.toStringAsFixed(0) ?? '120',
+ distanceByPassenger.toString() ?? '2000',
+ paymentController.isWalletChecked.toString(),
+ driverData['token'].toString(),
+ durationToPassenger.toString(),
+ rideId.toString(),
+ rideTimerBegin.toString(),
+ driverData['driver_id'].toString(),
+ durationToRide.toString(),
+ Get.find().wayPoints.length > 1
+ ? 'haveSteps'
+ : 'startEnd',
+ placesCoordinate[0],
+ placesCoordinate[1],
+ placesCoordinate[2],
+ placesCoordinate[3],
+ placesCoordinate[4],
+ costForDriver.toStringAsFixed(2),
+ (double.parse(box.read(BoxName.passengerWalletTotal)) < 0
+ ? double.parse(box.read(BoxName.passengerWalletTotal))
+ .toStringAsFixed(2)
+ : '0'),
+ box.read(BoxName.email).toString(),
+ data[0]['start_address'],
+ data[0]['end_address'],
+ box.read(BoxName.carType),
+ kazan.toStringAsFixed(0),
+ passengerRate.toStringAsFixed(2),
+ ];
+ }
+
+ StreamController _rideStatusStreamController =
+ StreamController.broadcast();
+ Stream get rideStatusStream => _rideStatusStreamController.stream;
+
+ Future delayAndFetchRideStatusForAllDriverAvailable(
+ String rideId) async {
const int maxAttempts = 15;
int attemptCounter = 0;
bool isApplied = false;
tick = 0;
- Log.print('tick delayAndFetchRideStatusForAllDriverAvailable: ${tick}');
+ await addRideToNotificationDriverAvailable();
+ Timer.periodic(const Duration(seconds: 1), (timer) async {
+ if (attemptCounter >= maxAttempts || isApplied) {
+ timer.cancel();
+ _rideStatusStreamController.close(); // Close the stream when done
+ return;
+ }
- void fetchRideStatus() async {
- if (attemptCounter < maxAttempts && !isApplied && tick < 20) {
- attemptCounter++;
- tick++;
+ attemptCounter++;
+ tick++;
+
+ try {
var res = await getRideStatus(rideId);
+ Log.print('res:2022 ${res}');
+ String rideStatusDelayed = res.toString();
+ Log.print('rideStatusDelayed: ${rideStatusDelayed}');
- if (res.toString() == 'Apply') {
- getUpdatedRideForDriverApply(rideId);
- isApplied = true;
- shouldFetch = false;
- statusRide = 'Apply';
- rideConfirm = false;
- isSearchingWindow = false;
- update();
- startTimerFromDriverToPassengerAfterApplied();
- } else if (attemptCounter >= maxAttempts) {
- shouldFetch = false;
- // If the status is still not "Apply" after 15 attempts
- MyDialog().getDialog('upgrade price'.tr,
- 'You can upgrade price to may driver accept your order'.tr, () {
+ _rideStatusStreamController
+ .add(rideStatusDelayed); // Emit the ride status
+ // addRideToNotificationDriverString();
+ if (rideStatusDelayed == 'Cancel') {
+ timer.cancel();
+ NotificationController().showNotification(
+ "Order Cancelled".tr, "you canceled order".tr, 'ding');
+ _rideStatusStreamController
+ .close(); // Close stream after cancellation
+ //
+ //
+ } else if (rideStatusDelayed == 'Apply' ||
+ rideStatusDelayed == 'Applied') {
+ rideAppliedFromDriver(isApplied);
+ timer.cancel();
+ // Close stream after applying
+ } else if (attemptCounter >= maxAttempts ||
+ rideStatusDelayed != 'Cancel') {
+ timer.cancel(); //todo
+ // addRideToNotificationDriverString();
+ // Show dialog to increase fee...
+ MyDialog().getDialog(
+ 'Are you want to wait drivers to 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: () {
- Get.back();
- cancelRide();
- }),
- MyElevatedButton(
- title: "Increase Fee".tr,
- kolor: AppColor.greenColor,
- onPressed: () {
- increaseFeeByPassengerAndReOrder();
- })
- ],
- );
+ addRideToNotificationDriverAvailable();
});
update();
- print('Stopped fetching ride status after 15 attempts.');
- } else {
- Timer(const Duration(seconds: 2), fetchRideStatus);
+ _rideStatusStreamController
+ .close(); // Close stream after max attempts
}
+ } catch (e) {
+ _rideStatusStreamController.addError(e); // Handle errors in the stream
}
- }
+ });
+ }
- fetchRideStatus(); // Initial call to start the process
+ rideAppliedFromDriver(bool isApplied) async {
+ 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');
+ if (box.read(BoxName.carType) == 'Speed' ||
+ box.read(BoxName.carType) == 'Awfar Car') {
+ NotificationController().showNotification(
+ 'The captain is responsible for the route.'.tr,
+ 'This price is fixed even if the route changes for the driver.'.tr,
+ 'ding');
+ } else if (box.read(BoxName.carType) == 'Comfort' ||
+ box.read(BoxName.carType) == 'Lady') {
+ NotificationController().showNotification('Attention'.tr,
+ 'The price may increase if the route changes.'.tr, 'ding');
+ }
+ isApplied = true;
+ statusRide = 'Apply';
+ rideConfirm = false;
+ isSearchingWindow = false;
+ update();
+ startTimer();
+// todo stop this because this method in startTimer()
+ // startTimerFromDriverToPassengerAfterApplied();
+
+ // timer.cancel();
+ _rideStatusStreamController.close();
+ }
+
+// Listening to the Stream
+ void listenToRideStatusStream() {
+ rideStatusStream.listen((rideStatus) {
+ print("Ride Status: $rideStatus");
+ // Handle updates based on the ride status
+ }, onError: (error) {
+ print("Error in Ride Status Stream: $error");
+ // Handle stream errors
+ }, onDone: () {
+ print("Ride status stream closed.");
+ });
}
reSearchAfterCanceledFromDriver() async {
- await getCarsLocationByPassengerAndReloadMarker(
- box.read(BoxName.carType), 7000);
-
- confirmRideForAllDriverAvailable();
shouldFetch = true; // Stop further fetches
statusRide = 'wait';
rideConfirm = true;
isSearchingWindow = true;
update();
+ updateConfirmRideForAllDriverAvailable();
}
void start15SecondTimer(String rideId) {
@@ -1485,44 +2154,56 @@ class MapPassengerController extends GetxController {
void timerEnded() async {
runEvery30SecondsUntilConditionMet();
isCancelRidePageShown = false;
- print('isCancelRidePageShown: ${isCancelRidePageShown}');
+ print('isCancelRidePageShown: $isCancelRidePageShown');
update();
}
Future getRideStatus(String rideId) async {
- final response =
- await CRUD().get(link: AppLink.getRideStatus, payload: {'id': rideId});
-
+ final response = await CRUD().get(
+ link: "${AppLink.endPoint}/ride/rides/getRideStatus.php",
+ payload: {'id': rideId});
+ print(response);
+ print('2140');
return jsonDecode(response)['data'];
}
- late String driverCarModel, driverCarMake, driverLicensePlate, driverName;
+ late String driverCarModel,
+ driverCarMake,
+ driverLicensePlate,
+ driverName = '';
getUpdatedRideForDriverApply(String rideId) async {
// if (isDriversTokensSend) {
- final res =
- await CRUD().get(link: AppLink.getRideOrderID, payload: {'id': rideId});
+ final res = await CRUD().get(
+ link: "${AppLink.endPoint}/ride/rides/getRideOrderID.php",
+ payload: {'id': rideId});
if (res != 'failure') {
var response = jsonDecode(res);
+ Log.print('getUpdatedRideForDriverApply: $response');
driverId = response['data']['driver_id'];
driverPhone = response['data']['phone'];
driverCarMake = response['data']['make'];
model = response['data']['model'];
+ colorHex = response['data']['color_hex'];
+ carColor = response['data']['color'];
make = response['data']['make'];
licensePlate = response['data']['car_plate'];
- firstName = response['data']['first_name'];
+ passengerName = response['data']['passengerName'];
+ driverName = response['data']['driverName'].toString();
driverToken = response['data']['token'];
+ // Log.print('driverToken updated: $driverToken');
carYear = response['data']['year'];
- driverRate = response['data']['ratingDriver'];
- }
- driversToken.remove(driverToken);
- for (var i = 1; i < driversToken.length; i++) {
- FirebaseMessagesController().sendNotificationToAnyWithoutData(
- 'Order Applied'.tr,
- '$driverName Apply order\nTake attention in other order'.tr,
- driversToken[i],
- 'start.wav',
- );
+ driverRate = response['data']['ratingDriver'].toString();
}
+ // driversToken.remove(driverToken);
+ // for (var i = 1; i < driversToken.length; i++) {
+ FirebaseMessagesController().sendNotificationToDriverMAP(
+ 'Order Accepted'.tr,
+ '$driverName${'Accepted your order'.tr}',
+ driverToken.toString(),
+ [],
+ 'start.wav',
+ );
+ // }
// }
}
@@ -1645,34 +2326,71 @@ class MapPassengerController extends GetxController {
final int updateIntervalMs = 100; // Update every 100ms
final double minMovementThreshold =
10; // Minimum movement in meters to trigger update
+ Future getCarForFirstConfirm(String carType) async {
+ bool foundCars = false;
+ int attempt = 0;
+
+ // Set up the periodic timer
+ Timer? timer = Timer.periodic(const Duration(seconds: 4), (Timer t) async {
+ // Attempt to get car location
+ foundCars = await getCarsLocationByPassengerAndReloadMarker(
+ carType, attempt * 2000);
+ Log.print('foundCars: $foundCars');
+
+ if (foundCars) {
+ // If cars are found, cancel the timer and exit the search
+ t.cancel();
+ } else if (attempt >= 4) {
+ // After 4 attempts, stop the search
+ t.cancel();
+
+ // No cars found after 4 attempts
+ // MyDialog().getDialog(
+ // "No Car or Driver Found in your area.".tr,
+ // "No Car or Driver Found in your area.".tr,
+ // () {
+ // Get.back();
+ // },
+ // );
+ if (!foundCars) {
+ noCarString = true;
+ dataCarsLocationByPassenger = 'failure';
+ }
+
+ update();
+ }
+
+ attempt++; // Increment attempt
+ });
+ }
void startCarLocationSearch(String carType) {
int searchInterval = 5; // Interval in seconds
- Log.print('searchInterval: ${searchInterval}');
+ Log.print('searchInterval: $searchInterval');
int boundIncreaseStep = 2500; // Initial bounds in meters
- Log.print('boundIncreaseStep: ${boundIncreaseStep}');
+ Log.print('boundIncreaseStep: $boundIncreaseStep');
int maxAttempts = 3; // Maximum attempts to increase bounds
int maxBoundIncreaseStep = 6000; // Maximum bounds increase step
int attempt = 0; // Current attempt
- Log.print('initial attempt: ${attempt}');
+ Log.print('initial attempt: $attempt');
Timer.periodic(Duration(seconds: searchInterval), (Timer timer) async {
- Log.print('Current attempt: ${attempt}'); // Log current attempt
+ Log.print('Current attempt: $attempt'); // Log current attempt
bool foundCars = false;
if (attempt >= maxAttempts) {
timer.cancel();
if (foundCars == false) {
noCarString = true;
- dataCarsLocationByPassenger = 'failure';
+ // dataCarsLocationByPassenger = 'failure';
update();
}
- return;
+ // return;
} else if (reloadStartApp == true) {
- Log.print('reloadStartApp: ${reloadStartApp}');
+ Log.print('reloadStartApp: $reloadStartApp');
foundCars = await getCarsLocationByPassengerAndReloadMarker(
carType, boundIncreaseStep);
- Log.print('foundCars: ${foundCars}');
+ Log.print('foundCars: $foundCars');
if (foundCars) {
timer.cancel();
@@ -1682,7 +2400,7 @@ class MapPassengerController extends GetxController {
timer.cancel();
}
Log.print(
- 'Incrementing attempt to: ${attempt}'); // Log incremented attempt
+ 'Incrementing attempt to: $attempt'); // Log incremented attempt
if (boundIncreaseStep < maxBoundIncreaseStep) {
boundIncreaseStep += 1500; // Increase bounds
@@ -1691,7 +2409,7 @@ class MapPassengerController extends GetxController {
maxBoundIncreaseStep; // Ensure it does not exceed the maximum
}
Log.print(
- 'New boundIncreaseStep: ${boundIncreaseStep}'); // Log new bounds
+ 'New boundIncreaseStep: $boundIncreaseStep'); // Log new bounds
}
}
}
@@ -1704,11 +2422,12 @@ class MapPassengerController extends GetxController {
longitude >= 31.215009 &&
longitude <= 31.532186) {
box.write(BoxName.serverChosen, AppLink.seferCairoServer);
+
return 'Cairo';
} else if (latitude >= 29.904975 &&
latitude <= 30.143372 &&
longitude >= 30.787030 &&
- longitude <= 31.238843) {
+ longitude <= 31.215009) {
box.write(BoxName.serverChosen, AppLink.seferGizaServer);
return 'Giza';
} else if (latitude >= 30.396286 &&
@@ -1719,114 +2438,141 @@ class MapPassengerController extends GetxController {
return 'Alexandria';
} else {
box.write(BoxName.serverChosen, AppLink.seferCairoServer);
- return 'Outside';
+ return 'Cairo';
}
}
Future getCarsLocationByPassengerAndReloadMarker(
String carType, int boundIncreaseStep) async {
- if (statusRide == 'wait') {
- carsLocationByPassenger = [];
- LatLngBounds bounds = calculateBounds(passengerLocation.latitude,
- passengerLocation.longitude, boundIncreaseStep.toDouble());
- var res;
- // await getLocation();
+ // if (statusRide == 'wait') {
+ carsLocationByPassenger = [];
+ LatLngBounds bounds = calculateBounds(passengerLocation.latitude,
+ passengerLocation.longitude, boundIncreaseStep.toDouble());
+ var res;
+ // await getLocation();
- switch (carType) {
- case 'Lady':
- res = await CRUD()
- .get(link: AppLink.getFemalDriverLocationByPassenger, payload: {
- 'southwestLat': bounds.southwest.latitude.toString(),
- 'southwestLon': bounds.southwest.longitude.toString(),
- 'northeastLat': bounds.northeast.latitude.toString(),
- 'northeastLon': bounds.northeast.longitude.toString(),
- });
- break;
- case 'Comfort':
- res = await CRUD()
- .get(link: AppLink.getCarsLocationByPassengerComfort, payload: {
- 'southwestLat': bounds.southwest.latitude.toString(),
- 'southwestLon': bounds.southwest.longitude.toString(),
- 'northeastLat': bounds.northeast.latitude.toString(),
- 'northeastLon': bounds.northeast.longitude.toString(),
- });
- break;
- case 'Speed':
- res = await CRUD()
- .get(link: AppLink.getCarsLocationByPassengerSpeed, payload: {
- 'southwestLat': bounds.southwest.latitude.toString(),
- 'southwestLon': bounds.southwest.longitude.toString(),
- 'northeastLat': bounds.northeast.latitude.toString(),
- 'northeastLon': bounds.northeast.longitude.toString(),
- });
- break;
- case 'Scooter':
- res = await CRUD()
- .get(link: AppLink.getCarsLocationByPassengerDelivery, payload: {
- 'southwestLat': bounds.southwest.latitude.toString(),
- 'southwestLon': bounds.southwest.longitude.toString(),
- 'northeastLat': bounds.northeast.latitude.toString(),
- 'northeastLon': bounds.northeast.longitude.toString(),
- });
- break;
- case 'Balash':
- res = await CRUD()
- .get(link: AppLink.getCarsLocationByPassengerBalash, payload: {
- 'southwestLat': bounds.southwest.latitude.toString(),
- 'southwestLon': bounds.southwest.longitude.toString(),
- 'northeastLat': bounds.northeast.latitude.toString(),
- 'northeastLon': bounds.northeast.longitude.toString(),
- });
- break;
- default:
- res = await CRUD()
- .get(link: AppLink.getCarsLocationByPassenger, payload: {
- 'southwestLat': bounds.southwest.latitude.toString(),
- 'southwestLon': bounds.southwest.longitude.toString(),
- 'northeastLat': bounds.northeast.latitude.toString(),
- 'northeastLon': bounds.northeast.longitude.toString(),
- });
- }
-
- if (res == 'failure') {
- noCarString = true;
- dataCarsLocationByPassenger = 'failure';
- update();
- return false;
- } else {
- noCarString = false;
- dataCarsLocationByPassenger = jsonDecode(res);
- driverId = dataCarsLocationByPassenger['message'][carsOrder]
- ['driver_id']
- .toString();
- gender = dataCarsLocationByPassenger['message'][carsOrder]['gender']
- .toString();
-
- carsLocationByPassenger.clear(); // Clear existing markers
-
- for (var i = 0;
- i < dataCarsLocationByPassenger['message'].length;
- i++) {
- var json = dataCarsLocationByPassenger['message'][i];
- _updateOrCreateMarker(
- MarkerId(json['latitude']).toString(),
- LatLng(double.parse(json['latitude']),
- double.parse(json['longitude'])),
- double.parse(json['heading']),
- _getIconForCar(json),
- );
-
- driversToken.add(json['token']);
- }
-
- // Add fake car markers
- _addFakeCarMarkers(passengerLocation, 2);
-
- update();
- return true;
- }
+ switch (carType) {
+ case 'Lady':
+ res = await CRUD()
+ .get(link: AppLink.getFemalDriverLocationByPassenger, payload: {
+ 'southwestLat': bounds.southwest.latitude.toString(),
+ 'southwestLon': bounds.southwest.longitude.toString(),
+ 'northeastLat': bounds.northeast.latitude.toString(),
+ 'northeastLon': bounds.northeast.longitude.toString(),
+ });
+ break;
+ case 'Comfort':
+ res = await CRUD()
+ .get(link: AppLink.getCarsLocationByPassengerComfort, payload: {
+ 'southwestLat': bounds.southwest.latitude.toString(),
+ 'southwestLon': bounds.southwest.longitude.toString(),
+ 'northeastLat': bounds.northeast.latitude.toString(),
+ 'northeastLon': bounds.northeast.longitude.toString(),
+ });
+ break;
+ case 'Speed':
+ res = await CRUD()
+ .get(link: AppLink.getCarsLocationByPassengerSpeed, payload: {
+ 'southwestLat': bounds.southwest.latitude.toString(),
+ 'southwestLon': bounds.southwest.longitude.toString(),
+ 'northeastLat': bounds.northeast.latitude.toString(),
+ 'northeastLon': bounds.northeast.longitude.toString(),
+ });
+ break;
+ case 'Scooter':
+ res = await CRUD()
+ .get(link: AppLink.getCarsLocationByPassengerDelivery, payload: {
+ 'southwestLat': bounds.southwest.latitude.toString(),
+ 'southwestLon': bounds.southwest.longitude.toString(),
+ 'northeastLat': bounds.northeast.latitude.toString(),
+ 'northeastLon': bounds.northeast.longitude.toString(),
+ });
+ break;
+ case 'Awfar Car':
+ res = await CRUD()
+ .get(link: AppLink.getCarsLocationByPassengerBalash, payload: {
+ 'southwestLat': bounds.southwest.latitude.toString(),
+ 'southwestLon': bounds.southwest.longitude.toString(),
+ 'northeastLat': bounds.northeast.latitude.toString(),
+ 'northeastLon': bounds.northeast.longitude.toString(),
+ });
+ break;
+ case 'Pink Bike':
+ res = await CRUD()
+ .get(link: AppLink.getCarsLocationByPassengerPinkBike, payload: {
+ 'southwestLat': bounds.southwest.latitude.toString(),
+ 'southwestLon': bounds.southwest.longitude.toString(),
+ 'northeastLat': bounds.northeast.latitude.toString(),
+ 'northeastLon': bounds.northeast.longitude.toString(),
+ });
+ break;
+ default:
+ res = await CRUD()
+ .get(link: AppLink.getCarsLocationByPassenger, payload: {
+ 'southwestLat': bounds.southwest.latitude.toString(),
+ 'southwestLon': bounds.southwest.longitude.toString(),
+ 'northeastLat': bounds.northeast.latitude.toString(),
+ 'northeastLon': bounds.northeast.longitude.toString(),
+ });
}
- return false;
+
+ if (res == 'failure') {
+ noCarString = true;
+ // dataCarsLocationByPassenger = 'failure';
+ update();
+ return false;
+ } else {
+ noCarString = false;
+ dataCarsLocationByPassenger = jsonDecode(res);
+ Log.print(
+ 'dataCarsLocationByPassenger:getCarsLocationByPassengerAndReloadMarker ${dataCarsLocationByPassenger}');
+
+ // Check if 'message' is present and not null
+ if (dataCarsLocationByPassenger != null &&
+ dataCarsLocationByPassenger.isNotEmpty) {
+ // Check if carsOrder is within bounds
+ // if (carsOrder < dataCarsLocationByPassenger['message'].length) {
+ // driverId = dataCarsLocationByPassenger['message'][carsOrder]
+ // ['driver_id']
+ // .toString();
+ // gender = dataCarsLocationByPassenger['message'][carsOrder]['gender']
+ // .toString();
+ // driverToken = dataCarsLocationByPassenger['message'][carsOrder]
+ // ['token']
+ // .toString();
+ // } else {
+ print('carsOrder is in of bounds for message array');
+ // return false;
+ // }
+ } else {
+ // Get.defaultDialog(title: 'No cars available ');
+ print('No cars available or message is null');
+ return false;
+ }
+
+ carsLocationByPassenger.clear(); // Clear existing markers
+
+ for (var i = 0; i < dataCarsLocationByPassenger['message'].length; i++) {
+ var json = dataCarsLocationByPassenger['message'][i];
+ _updateOrCreateMarker(
+ MarkerId(json['latitude']).toString(),
+ LatLng(
+ double.parse(json['latitude']), double.parse(json['longitude'])),
+ double.parse(json['heading']),
+ _getIconForCar(json),
+ );
+
+ driversToken.add(json['token']);
+ }
+
+ // Add fake car markers
+ _addFakeCarMarkers(passengerLocation, 1);
+
+ update();
+ return true;
+ }
+ // }
+ // return false;
}
final List