25-6-23/1

This commit is contained in:
Hamza-Ayed
2025-06-23 02:24:42 +03:00
parent 5eba032887
commit 5050aab9b7
42 changed files with 2387 additions and 1783 deletions

14
.env
View File

@@ -32,18 +32,18 @@ geminiApi=QOmqZsQYm08vOqjI7klVJfvP4WBFEoemjgy396iXrXlBl
geminiApiMasa=QOmqZsQIdM4BRsKmaDJOP7dZp5-c6NWfch7PAlQXrXlBl geminiApiMasa=QOmqZsQIdM4BRsKmaDJOP7dZp5-c6NWfch7PAlQXrXlBl
agoraAppId=71880f2j636509j24y5294480y30u848XrXlBl agoraAppId=71880f2j636509j24y5294480y30u848XrXlBl
agoraAppCertificate=j17q944u49390q758u1649448q2y6xfuXrXlBl agoraAppCertificate=j17q944u49390q758u1649448q2y6xfuXrXlBl
usernamePayMob=37319104052XrXlBl usernamePayMob=373191e04052XrXlBl
passwordPayMob='g@nkD2#99!hD_.wXrXlBl' passwordPayMob='g@nkD23#99!hD_.wXrXlBl'
integrationIdPayMob=0237730XrXlBl integrationIdPayMob=02337730XrXlBl
payMobApikey='MDrGqKEWS1rVqHvEPDvPjJ7vZDBExrO7S3BEBgrlfUwTA3i5RnP5ZnvoL3M2S9rEBgrlNTdexH5pTPf7NJrvy1reZJv1Tn7zf7vTIDywjHg1C7Ley38HTDyNA3v7TPfdxJrax1rwPmPtMJyzqKEYZeghq3MuLUrFH3A1AgHcH15CZ9UaZTLOxnw0BTdzHHrBArisZerUMUUzZ1BnBeEijHvNjYLnS1BUICMhSmPhA15ifHyVqKEMHWyKLbyuIPvcH9UeL3vZyDf=XrXlBl' payMobApikey='MDrGqKEWS14rVqHvEPDvPjJ7vZDBExrO7S3BEBgrlfUwTA3i5fRnP5ZnvoL3M2S9rEBgrlNTdexH5pTPf7NJrvy1reZJv1Tn7zf7vTIDywjHg1C7Ley38HTDyNA3v7TPfdxJrax1rwPmPtMJyzqKEYZeghq3MuLUrFH3A1AgHcH15CZ9UaZTLOxnw0BTdzHHrBArisZerUMUUzZ1BnBeEijHvNjYLnS1BUICMhSmPhA15ifHyVqKEMHWyKLbyuIPvcH9UeL3vZyDf=XrXlBl'
integrationIdPayMobWallet=0237739XrXlBl integrationIdPayMobWallet=0237731XrXlBl
ocpApimSubscriptionKey=0f5dacccdbce4131b1a5f952996302e3 ocpApimSubscriptionKey=0f5dacccdbce4131b1a5f952996302e3
smsPasswordEgypt="J)Vh=qb/@MXrXlBl" smsPasswordEgypt="J)Vh=qb/@MXrXlBl"
chatGPTkeySeferNew4=zg-vlie-2l1ZlpxiLJ6wQOvbb4TnC9XrxgUEyVQIu6TID4qP4FUUqoS5XrXlBl chatGPTkeySeferNew4=zg-vlie-2l1ZlpxiLJ6wQOvbb4TnC9XrxgUEyVQIu6TID4qP4FUUqoS5XrXlBl
anthropicAIkeySeferNew=zg-qbc-qvo39-n4VdMQ5nuJeIYhMN4PDYr7qox3-t2i1Lh7aNTDfYF-Gf8whUJZCs47EeelKn8_UcmUMmiSLaf0UJg0DvUlQrDt-76CRrkQQXrXlBl anthropicAIkeySeferNew=zg-qbc-qvo39-n4VdMQ5nuJeIYhMN4PDYr7qox3-t2i1Lh7aNTDfYF-Gf8whUJZCs47EeelKn8_UcmUMmiSLaf0UJg0DvUlQrDt-76CRrkQQXrXlBl
llama3Key=kzg_uTXy3e9DBbCQ1FnMGxYwTKysx9US1burxJj4fFwOje4LZBUFKJS1XrXlBl llama3Key=kzg_uTXy3e9DBbCQ1FnMGxYwTKysx9US1burxJj4fFwOje4LZBUFKJS1XrXlBl
payMobOutPassword='D2zJFxkE#LN3vz38z2dYxpNfWXrXlBl' payMobOutPassword='D2zJFxkE#LN43vz328z2dYxpNfWXrXlBl'
payMobOutUserName='zjujl_qvo_fwjfgjlXrXlBl' payMobOutUserName='zjujl_qfvo_fwjf36gjlXrXlBl'
keyOfApp=nqryjjjhgjp@1bCQ1FnMGxYwsjyzjujljksvceiXrXlBl keyOfApp=nqryjjjhgjp@1bCQ1FnMGxYwsjyzjujljksvceiXrXlBl
initializationVector=ujljkdelkjlXrXlBlfghijkl initializationVector=ujljkdelkjlXrXlBlfghijkl
sss_pass=wqnmqqsjyvwv:nqrYJP@17378XrXlBl sss_pass=wqnmqqsjyvwv:nqrYJP@17378XrXlBl

View File

@@ -2,28 +2,28 @@ C/C++ Structured Log
 
}/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/arm64-v8a/additional_project_files.txtC }/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/arm64-v8a/additional_project_files.txtC
A A
?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  Ô¶õ§ö2  ÿÊü××2~ ?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  ޶´Áù2  ÿÊü××2~
| |
z/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/arm64-v8a/android_gradle_build.json  Õ¶õ§ö2ù z/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/arm64-v8a/android_gradle_build.json  ޶´Áù2ù
˜Ëü××2„ ˜Ëü××2„
<EFBFBD> <EFBFBD>
/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/arm64-v8a/android_gradle_build_mini.json  Õ¶õ§ö2» êÐü××2p /Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/arm64-v8a/android_gradle_build_mini.json  ޶´Áù2» êÐü××2p
n n
l/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/arm64-v8a/build.ninja  Õ¶õ§ö2⃠†Åü××2t l/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/arm64-v8a/build.ninja  ޶´Áù2⃠†Åü××2t
r r
p/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/arm64-v8a/build.ninja.txt  Õ¶õ§ö2y p/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/arm64-v8a/build.ninja.txt  ޶´Áù2y
w w
u/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/arm64-v8a/build_file_index.txt  Õ¶õ§ö2 u/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/arm64-v8a/build_file_index.txt  ޶´Áù2
^ €<>àÕ×2z ^ €<>àÕ×2z
x x
v/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/arm64-v8a/compile_commands.json  ޶´Áù2« „Åü××2~ v/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/arm64-v8a/compile_commands.json  ޶´Áù2« „Åü××2~
| |
z/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/arm64-v8a/compile_commands.json.bin  ޶´Áù2 Æ „Åü××2† z/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/arm64-v8a/compile_commands.json.bin  ޶´Áù2 Æ „Åü××2†
ƒ ƒ
/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/arm64-v8a/metadata_generation_command.txt  ޶´Áù2 /Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/arm64-v8a/metadata_generation_command.txt  ޶´Áù2
Š €<>àÕ×2w Š €<>àÕ×2w
u u
s/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/arm64-v8a/prefab_config.json  ޶´Áù2 s/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/arm64-v8a/prefab_config.json  ޶´Áù2
 ( €<>àÕ×2|  ( €<>àÕ×2|
z z
x/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/arm64-v8a/symbol_folder_index.txt  Õ¶õ§ö2 x/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/arm64-v8a/symbol_folder_index.txt  ޶´Áù2

View File

@@ -2,27 +2,27 @@ C/C++ Structured Log
<EFBFBD> <EFBFBD>
/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/armeabi-v7a/additional_project_files.txtC /Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/armeabi-v7a/additional_project_files.txtC
A A
?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  ®·õ§ö2  éòü××2€ ?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  Œ·´Áù2  éòü××2€
~ ~
|/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/armeabi-v7a/android_gradle_build.json  ®·õ§ö2<18> ïòü××2‡ |/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/armeabi-v7a/android_gradle_build.json  Œ·´Áù2<18> ïòü××2‡
 
<EFBFBD>/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/armeabi-v7a/android_gradle_build_mini.json  ®·õ§ö2à ùòü××2r <EFBFBD>/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/armeabi-v7a/android_gradle_build_mini.json  Œ·´Áù2à ùòü××2r
p p
n/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/armeabi-v7a/build.ninja  ®·õ§ö2¨„ ¯òü××2v n/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/armeabi-v7a/build.ninja  Œ·´Áù2¨„ ¯òü××2v
t t
r/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/armeabi-v7a/build.ninja.txt  ®·õ§ö2{ r/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/armeabi-v7a/build.ninja.txt  Œ·´Áù2{
y y
w/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/armeabi-v7a/build_file_index.txt  ®·õ§ö2 w/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/armeabi-v7a/build_file_index.txt  Œ·´Áù2
^ “¤àÕ×2| ^ “¤àÕ×2|
z z
x/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/armeabi-v7a/compile_commands.json  Œ·´Áù2Æ ®òü××2€ x/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/armeabi-v7a/compile_commands.json  Œ·´Áù2Æ ®òü××2€
~ ~
|/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/armeabi-v7a/compile_commands.json.bin  Œ·´Áù2 ï ®òü××2ˆ |/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/armeabi-v7a/compile_commands.json.bin  Œ·´Áù2 ï ®òü××2ˆ
 
/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/armeabi-v7a/metadata_generation_command.txt  <08>·´Áù2 /Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/armeabi-v7a/metadata_generation_command.txt  <08>·´Áù2
” “¤àÕ×2y ” “¤àÕ×2y
w w
u/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/armeabi-v7a/prefab_config.json  <08>·´Áù2 u/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/armeabi-v7a/prefab_config.json  <08>·´Áù2
 ( “¤àÕ×2~  ( “¤àÕ×2~
| |
z/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/armeabi-v7a/symbol_folder_index.txt  ®·õ§ö2 z/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/armeabi-v7a/symbol_folder_index.txt  <EFBFBD>·´Áù2

View File

@@ -2,28 +2,28 @@ C/C++ Structured Log{
y y
w/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86/additional_project_files.txtC w/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86/additional_project_files.txtC
A A
?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  É·õ§ö2  þÿü××2x ?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  ¢·´Áù2  þÿü××2x
v v
t/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86/android_gradle_build.json  É·õ§ö2á t/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86/android_gradle_build.json  ¢·´Áù2á
€ý××2} €ý××2}
{ {
y/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86/android_gradle_build_mini.json  É·õ§ö2£ †€ý××2j y/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86/android_gradle_build_mini.json  ¢·´Áù2£ †€ý××2j
h h
f/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86/build.ninja  É·õ§ö2²ƒ Üÿü××2n f/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86/build.ninja  ¢·´Áù2²ƒ Üÿü××2n
l l
j/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86/build.ninja.txt  É·õ§ö2s j/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86/build.ninja.txt  ¢·´Áù2s
q q
o/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86/build_file_index.txt  É·õ§ö2 o/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86/build_file_index.txt  ¢·´Áù2
^ ªÕàÕ×2t ^ ªÕàÕ×2t
r r
p/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86/compile_commands.json  ¢·´Áù2± Ûÿü××2x p/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86/compile_commands.json  ¢·´Áù2± Ûÿü××2x
v v
t/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86/compile_commands.json.bin  ¢·´Áù2 Ó Ûÿü××2~ t/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86/compile_commands.json.bin  ¢·´Áù2 Ó Ûÿü××2~
| |
z/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86/metadata_generation_command.txt  ¢·´Áù2 z/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86/metadata_generation_command.txt  ¢·´Áù2
ì ©ÕàÕ×2q ì ©ÕàÕ×2q
o o
m/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86/prefab_config.json  ¢·´Áù2 m/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86/prefab_config.json  ¢·´Áù2
 ( ©ÕàÕ×2v  ( ©ÕàÕ×2v
t t
r/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86/symbol_folder_index.txt  É·õ§ö2 r/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86/symbol_folder_index.txt  ¢·´Áù2

View File

@@ -2,28 +2,28 @@ C/C++ Structured Log~
| |
z/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86_64/additional_project_files.txtC z/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86_64/additional_project_files.txtC
A A
?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  ß·õ§ö2  ûŠý××2{ ?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  ··´Áù2  ûŠý××2{
y y
w/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86_64/android_gradle_build.json  ß·õ§ö2í w/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86_64/android_gradle_build.json  ··´Áù2í
ýŠý××2€ ýŠý××2€
~ ~
|/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86_64/android_gradle_build_mini.json  ß·õ§ö2¯ý××2m |/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86_64/android_gradle_build_mini.json  ··´Áù2¯ý××2m
k k
i/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86_64/build.ninja  ß·õ§ö2¼ƒ çŠý××2q i/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86_64/build.ninja  ··´Áù2¼ƒ çŠý××2q
o o
m/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86_64/build.ninja.txt  ß·õ§ö2v m/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86_64/build.ninja.txt  ··´Áù2v
t t
r/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86_64/build_file_index.txt  ß·õ§ö2 r/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86_64/build_file_index.txt  ··´Áù2
^ ŒààÕ×2w ^ ŒààÕ×2w
u u
s/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86_64/compile_commands.json  ··´Áù2§ çŠý××2{ s/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86_64/compile_commands.json  ··´Áù2§ çŠý××2{
y y
w/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86_64/compile_commands.json.bin  ··´Áù2  çŠý××2<C397> w/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86_64/compile_commands.json.bin  ··´Áù2  çŠý××2<C397>
 
}/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86_64/metadata_generation_command.txt  ··´Áù2 }/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86_64/metadata_generation_command.txt  ··´Áù2
û ŒààÕ×2t û ŒààÕ×2t
r r
p/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86_64/prefab_config.json  ··´Áù2 p/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86_64/prefab_config.json  ··´Áù2
 ( ŒààÕ×2y  ( ŒààÕ×2y
w w
u/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86_64/symbol_folder_index.txt  ß·õ§ö2 u/Users/hamzaaleghwairyeen/development/App/driver_sefer/android/app/.cxx/Debug/6a58wo5c/x86_64/symbol_folder_index.txt  ··´Áù2

View File

@@ -24,34 +24,30 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" /> <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.QUICKBOOT_POWERON" /> <uses-permission android:name="android.permission.QUICKBOOT_POWERON" />
<uses-permission android:name="com.htc.intent.action.QUICKBOOT_POWERON" /> <uses-permission android:name="com.htc.intent.action.QUICKBOOT_POWERON" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<application <application
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/launcher_icon" android:icon="@mipmap/launcher_icon"
android:label="Tripz Driver" android:label="Tripz Driver"
android:theme="@style/LaunchTheme"> android:theme="@style/LaunchTheme">
<service
android:name=".MyFirebaseMessagingService"
android:exported="false"></service>
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:configChanges="orientation|keyboardHidden|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:exported="true" android:exported="true"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:launchMode="singleTask" android:launchMode="singleTask"
android:theme="@style/LaunchTheme" android:theme="@style/LaunchTheme"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<meta-data <meta-data android:name="io.flutter.embedding.android.NormalTheme"
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme" /> android:resource="@style/NormalTheme" />
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
@@ -62,85 +58,50 @@
android:name="com.yalantis.ucrop.UCropActivity" android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
<meta-data
android:name="com.google.android.geo.API_KEY" <meta-data android:name="com.google.android.geo.API_KEY" android:value="@string/api_key" />
android:value="@string/api_key" /> <meta-data android:name="com.google.firebase.messaging.default_notification_channel_id"
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="@string/default_notification_channel_id" /> android:value="@string/default_notification_channel_id" />
<meta-data <meta-data android:name="flutterEmbedding" android:value="2" />
android:name="flutterEmbedding"
android:value="2" />
<service <service android:name=".MyFirebaseMessagingService" android:exported="false" />
android:name=".LocationUpdatesService" <service android:name=".LocationUpdatesService" android:exported="false"
android:exported="false"
android:foregroundServiceType="location" /> android:foregroundServiceType="location" />
<service android:name="com.google.firebase.messaging.FirebaseMessagingService"
android:exported="false" tools:replace="android:exported">
<!-- <service
android:name=".java.MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service> -->
<service
android:name="com.google.firebase.messaging.FirebaseMessagingService"
android:exported="false"
tools:replace="android:exported">
<intent-filter> <intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" /> <action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter> </intent-filter>
</service> </service>
<service <service android:name="com.phan_tech.flutter_overlay_apps.OverlayService"
android:name="com.phan_tech.flutter_overlay_apps.OverlayService"
android:exported="false" /> android:exported="false" />
<service <service android:name="flutter.overlay.window.flutter_overlay_window.OverlayService"
android:name="flutter.overlay.window.flutter_overlay_window.OverlayService"
android:foregroundServiceType="specialUse"> android:foregroundServiceType="specialUse">
<property <property android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
android:value="explanation_for_special_use" /> android:value="explanation_for_special_use" />
</service> </service>
<receiver <receiver android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver"
android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND">
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter> <intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" /> <action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.sefer_driver" /> <category android:name="com.sefer_driver" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<service <service android:name="com.dsaved.bubblehead.bubble.BubbleHeadService" android:enabled="true"
android:name="com.dsaved.bubblehead.bubble.BubbleHeadService"
android:enabled="true"
android:exported="false"> android:exported="false">
<intent-filter> <intent-filter>
<action android:name="intent.bring.app.to.foreground" /> <action android:name="intent.bring.app.to.foreground" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
</intent-filter> </intent-filter>
</service> </service>
<!-- <receiver <receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver"
android:exported="false" />
<receiver
android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver" android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver"
android:exported="true"> android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver> -->
<receiver android:exported="false"
android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver" />
<receiver android:exported="false"
android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" /> <action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
@@ -148,9 +109,8 @@
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON" /> <action android:name="com.htc.intent.action.QUICKBOOT_POWERON" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver
android:name=".YourBroadcastReceiver"
android:exported="false" />
</application>
<receiver android:name=".YourBroadcastReceiver" android:exported="false" />
</application>
</manifest> </manifest>

View File

@@ -1,6 +1,7 @@
package com.sefer_driver package com.sefer_driver
import android.app.AlertDialog import android.app.AlertDialog
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.widget.LinearLayout import android.widget.LinearLayout
@@ -9,137 +10,129 @@ import android.widget.TextView
import androidx.core.view.setPadding import androidx.core.view.setPadding
import com.scottyab.rootbeer.RootBeer import com.scottyab.rootbeer.RootBeer
import io.flutter.embedding.android.FlutterFragmentActivity import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import java.io.File import java.io.File
import java.util.Timer import java.util.Timer
import kotlin.concurrent.schedule import kotlin.concurrent.schedule
import io.flutter.embedding.engine.FlutterEngine // Import FlutterEngine
import io.flutter.plugin.common.MethodChannel // Import MethodChannel
import io.flutter.plugin.common.MethodCall // Import MethodCall
import io.flutter.plugin.common.MethodChannel.Result // Import Result
class MainActivity : FlutterFragmentActivity() { class MainActivity : FlutterFragmentActivity() {
private val SECURITY_CHANNEL = "com.sefer_driver/security"
private lateinit var channel: MethodChannel // Declare a MethodChannel variable private val APP_CONTROL_CHANNEL = "com.sefer_driver/app_control"
override fun configureFlutterEngine(flutterEngine: FlutterEngine) { override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine) super.configureFlutterEngine(flutterEngine)
// Initialize the MethodChannel // Channel for security checks (isRooted)
channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "com.sefer_driver/security") MethodChannel(flutterEngine.dartExecutor.binaryMessenger, SECURITY_CHANNEL)
.setMethodCallHandler { call, result ->
// Set a MethodCallHandler to handle method calls from Flutter
channel.setMethodCallHandler { call, result ->
when (call.method) { when (call.method) {
"isNativeRooted" -> { "isNativeRooted" -> result.success(isDeviceCompromised())
val isCompromised = isDeviceCompromised() else -> result.notImplemented()
result.success(isCompromised) // Send the result back to Flutter
}
else -> {
result.notImplemented() // Handle unknown method calls
}
}
} }
} }
// Channel for app control (bringing to foreground)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, APP_CONTROL_CHANNEL)
.setMethodCallHandler { call, result ->
when (call.method) {
"bringToForeground" -> {
Log.d("MainActivity", "Received bringToForeground request")
val intent =
Intent(this, MainActivity::class.java).apply {
action = Intent.ACTION_MAIN
addCategory(Intent.CATEGORY_LAUNCHER)
addFlags(
Intent.FLAG_ACTIVITY_NEW_TASK or
Intent.FLAG_ACTIVITY_CLEAR_TOP or
Intent.FLAG_ACTIVITY_SINGLE_TOP
)
}
try {
startActivity(intent)
Log.d(
"MainActivity",
"App brought to foreground successfully with flags: ${intent.flags}"
)
result.success(true)
} catch (e: Exception) {
Log.e(
"MainActivity",
"Error bringing app to foreground: ${e.message}",
e
)
result.error(
"ACTIVITY_START_FAILED",
e.message,
e.stackTraceToString()
)
}
}
else -> result.notImplemented()
}
}
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
Log.d("MainActivity", "MainActivity onCreate")
// Perform all checks. The order can matter; you might want to prioritize
// the faster checks first.
if (isDeviceCompromised()) { if (isDeviceCompromised()) {
showSecurityWarningDialog() showSecurityWarningDialog()
} }
} }
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
setIntent(intent)
Log.d("MainActivity", "Received new intent: ${intent.action}, flags: ${intent.flags}")
}
private fun isDeviceCompromised(): Boolean { private fun isDeviceCompromised(): Boolean {
return try { return try {
nativeRootCheck() || rootBeerCheck() //|| !safetyNetCheck() val isRootedByRootBeer = RootBeer(this).isRooted
Log.d("MainActivity", "Root check result: $isRootedByRootBeer")
isRootedByRootBeer
} catch (e: Exception) { } catch (e: Exception) {
Log.e("DEBUG", "Error during security checks: ${e.message}", e) Log.e("MainActivity", "Security check error: ${e.message}", e)
true // Consider the device compromised on error true // Fail-safe: assume compromised if check fails
} }
} }
private fun nativeRootCheck(): Boolean {
Log.d("DEBUG", "Starting native root detection...")
return try {
val isNativeRooted = RootDetection.isNativeRooted()
Log.d("DEBUG", "Native root detection result: $isNativeRooted")
isNativeRooted
} catch (e: Exception) {
Log.e("DEBUG", "Error in native root detection: ${e.message}", e)
true // Consider rooted on exception
}
}
private fun rootBeerCheck(): Boolean {
Log.d("DEBUG", "Starting RootBeer root detection...")
val rootBeer = RootBeer(this)
val isRooted = rootBeer.isRooted
Log.d("DEBUG", "RootBeer detection result: $isRooted")
return isRooted
}
private fun safetyNetCheck(): Boolean {
Log.d("DEBUG", "Starting SafetyNet check...")
var isSafe = false // Initialize a variable to store result
val semaphore = java.util.concurrent.Semaphore(0) // Create a semaphore
SafetyNetCheck.checkSafetyNet(this, getString(R.string.api_key_safety)) { result ->
isSafe = result
Log.d("DEBUG", "SafetyNet check result: $isSafe")
semaphore.release() // Release the semaphore when the callback is executed
}
try {
semaphore.acquire() // Wait for the callback to complete
} catch (e: InterruptedException) {
Log.e("DEBUG", "Interrupted while waiting for SafetyNet check", e)
return false // Or handle as appropriate for your app
}
return isSafe
}
private fun showSecurityWarningDialog() { private fun showSecurityWarningDialog() {
var secondsRemaining = 10 // Start at 10 seconds var secondsRemaining = 10
val progressBar =
// Create views programmatically ProgressBar(this, null, android.R.attr.progressBarStyleHorizontal).apply {
val progressBar = ProgressBar(this, null, android.R.attr.progressBarStyleHorizontal) max = 10
progressBar.max = 10 // Set max to 10 for 10 seconds progress = 10
progressBar.progress = 10 // Start full }
val textView = TextView(this) val textView =
textView.text = getString(R.string.security_warning_message) // Your message TextView(this).apply {
textView.textAlignment = TextView.TEXT_ALIGNMENT_CENTER text = getString(R.string.security_warning_message)
textAlignment = TextView.TEXT_ALIGNMENT_CENTER
val layout = LinearLayout(this) }
layout.orientation = LinearLayout.VERTICAL val layout =
layout.setPadding(48) LinearLayout(this).apply {
layout.addView(textView) orientation = LinearLayout.VERTICAL
layout.addView(progressBar) setPadding(48)
addView(textView)
addView(progressBar)
}
val dialog = val dialog =
AlertDialog.Builder(this) AlertDialog.Builder(this)
.setTitle(getString(R.string.security_warning_title)) // Your title .setTitle(getString(R.string.security_warning_title))
.setView(layout) // Set the custom layout .setView(layout)
.setCancelable( .setCancelable(false)
false
) // Prevent dismissing by tapping outside or back button
.create() .create()
dialog.show() dialog.show()
// Use a Timer to update the progress bar and countdown
val timer = Timer() val timer = Timer()
timer.schedule(0, 1000) { // Update every 1000ms (1 second) timer.schedule(0, 1000) {
secondsRemaining-- secondsRemaining--
runOnUiThread { // Update UI on the main thread runOnUiThread {
progressBar.progress = progressBar.progress = secondsRemaining
secondsRemaining // Set the progress bar to show remaining seconds
if (secondsRemaining <= 0) { if (secondsRemaining <= 0) {
timer.cancel() // Stop the timer timer.cancel()
dialog.dismiss() // Dismiss the dialog dialog.dismiss()
clearAppDataAndExit() // Clear data and exit clearAppDataAndExit()
} }
} }
} }
@@ -147,56 +140,35 @@ class MainActivity : FlutterFragmentActivity() {
private fun clearAppDataAndExit() { private fun clearAppDataAndExit() {
try { try {
val packageName = applicationContext.packageName Runtime.getRuntime().exec("pm clear $packageName")
val runtime = Runtime.getRuntime() Log.d("MainActivity", "Cleared app data via package manager")
runtime.exec("pm clear $packageName") // Clear app data
} catch (e: Exception) { } catch (e: Exception) {
Log.e("MainActivity", "Error clearing app data: ${e.message}", e)
clearCache() clearCache()
clearAppData() clearAppData()
} }
finishAffinity()
finishAffinity() // Finish all activities from this app System.exit(0)
System.exit(0) // Terminate the app's process
} }
private fun clearCache() { private fun clearCache() {
try {
val cacheDir = cacheDir
if (cacheDir != null && cacheDir.isDirectory) {
deleteDir(cacheDir) deleteDir(cacheDir)
}
val externalCacheDir = externalCacheDir
if (externalCacheDir != null && externalCacheDir.isDirectory) {
deleteDir(externalCacheDir) deleteDir(externalCacheDir)
} Log.d("MainActivity", "Cleared cache directories")
} catch (e: Exception) {
Log.e("DEBUG", "Error clearing cache: ${e.message}", e)
}
} }
private fun clearAppData() { private fun clearAppData() {
try { // Be careful with this, it deletes all app data.
val dataDir = applicationContext.dataDir // deleteDir(applicationContext.dataDir)
if (dataDir != null && dataDir.isDirectory) { Log.d("MainActivity", "App data clearing skipped (commented out)")
deleteDir(dataDir)
}
} catch (e: Exception) {
Log.e("DEBUG", "Error clearing app data: ${e.message}", e)
}
} }
private fun deleteDir(dir: File?): Boolean { private fun deleteDir(dir: File?): Boolean {
if (dir != null && dir.isDirectory) { if (dir != null && dir.isDirectory) {
val children = dir.list() dir.list()?.forEach { deleteDir(File(dir, it)) }
if (children != null) { }
for (child in children) { val deleted = dir?.delete() ?: false
val success = deleteDir(File(dir, child)) Log.d("MainActivity", "Deleted directory ${dir?.path}: $deleted")
if (!success) { return deleted
return false
}
}
}
}
return dir?.delete() ?: false
} }
} }

View File

@@ -6,6 +6,10 @@ class BoxName {
static const String initializationVector = 'initializationVector'; static const String initializationVector = 'initializationVector';
static const String firstTimeLoadKey = 'firstTimeLoadKey'; static const String firstTimeLoadKey = 'firstTimeLoadKey';
static const String jwt = "jwt"; static const String jwt = "jwt";
static const String rideId = "rideId";
static const String rideArgumentsFromBackground =
"rideArgumentsFromBackground";
static const String FCM_PRIVATE_KEY = "FCM_PRIVATE_KEY";
static const String hmac = "hmac"; static const String hmac = "hmac";
static const String fingerPrint = "fingerPrint"; static const String fingerPrint = "fingerPrint";
static const String payMobApikey = "payMobApikey"; static const String payMobApikey = "payMobApikey";

View File

@@ -101,6 +101,10 @@ class AppLink {
static String getTripCountByCaptain = "$ride/rides/getTripCountByCaptain.php"; static String getTripCountByCaptain = "$ride/rides/getTripCountByCaptain.php";
static String getRideOrderID = "$ride/rides/getRideOrderID.php"; static String getRideOrderID = "$ride/rides/getRideOrderID.php";
static String getRideStatus = "$ride/rides/getRideStatus.php"; static String getRideStatus = "$ride/rides/getRideStatus.php";
static String getOverLayStatus = "$ride/overLay/get.php";
static String getArgumentAfterAppliedFromBackground =
"$ride/overLay/getArgumentAfterAppliedFromBackground.php";
static String addOverLayStatus = "$ride/overLay/add.php";
static String getapiKey = "$ride/apiKey/get.php"; static String getapiKey = "$ride/apiKey/get.php";
static String getapiKeySefer = "$ride/apiKey/get.php"; static String getapiKeySefer = "$ride/apiKey/get.php";
@@ -123,6 +127,12 @@ class AppLink {
////-----------------DriverPayment------------------ ////-----------------DriverPayment------------------
static String addDrivePayment = "$seferPaymentServer/ride/payment/add.php"; static String addDrivePayment = "$seferPaymentServer/ride/payment/add.php";
static String payWithPayMobCardDriver =
"$seferPaymentServer/ride/payMob/paymob_driver/payWithCard.php";
static String payWithWallet =
"$seferPaymentServer/ride/payMob/paymob_driver/payWithWallet.php";
static String paymetVerifyDriver =
"$seferPaymentServer/ride/payMob/paymob_driver/paymet_verfy.php";
static String updatePaymetToPaid = static String updatePaymetToPaid =
"$seferPaymentServer/ride/payment/updatePaymetToPaid.php"; "$seferPaymentServer/ride/payment/updatePaymetToPaid.php";

View File

@@ -188,16 +188,16 @@ Download the Tripz app now and enjoy your ride!
(driverInvitationData[index]['driverInviterId']), (driverInvitationData[index]['driverInviterId']),
('500'), ('500'),
); );
await Get.find<CaptainWalletController>() // await Get.find<CaptainWalletController>()
.addSeferWallet('giftInvitation', ('-1000')); // .addSeferWallet('giftInvitation', ('-1000'));
NotificationCaptainController().addNotificationCaptain( NotificationCaptainController().addNotificationCaptain(
driverInvitationData[index]['driverInviterId'].toString(), driverInvitationData[index]['driverInviterId'].toString(),
"You have got a gift for invitation".tr, "You have got a gift for invitation".tr,
'${"You have 500".tr} ${'LE'}', '${"You have 500".tr} ${'LE'.tr}',
false); false);
NotificationController().showNotification( NotificationController().showNotification(
"You have got a gift for invitation".tr, "You have got a gift for invitation".tr,
'${"You have 500".tr} ${'LE'}', '${"You have 500".tr} ${'LE'.tr}',
'tone1', 'tone1',
''); '');
} else { } else {
@@ -264,6 +264,7 @@ Download the Tripz app now and enjoy your ride!
link: AppLink.updatePassengerGift, link: AppLink.updatePassengerGift,
payload: {'id': driverInvitationDataToPassengers[index]['id']}, payload: {'id': driverInvitationDataToPassengers[index]['id']},
); );
// Notify the inviter // Notify the inviter
NotificationCaptainController().addNotificationCaptain( NotificationCaptainController().addNotificationCaptain(
driverInvitationDataToPassengers[index]['passengerInviterId'] driverInvitationDataToPassengers[index]['passengerInviterId']

View File

@@ -98,7 +98,7 @@ class LoginDriverController extends GetxController {
final random = Random(); final random = Random();
if (random.nextBool()) { if (random.nextBool()) {
// await SecurityHelper.performSecurityChecks(); await SecurityHelper.performSecurityChecks();
} else { } else {
await SecurityChecks.isDeviceRootedFromNative(Get.context!); await SecurityChecks.isDeviceRootedFromNative(Get.context!);
} }
@@ -145,20 +145,21 @@ class LoginDriverController extends GetxController {
); );
if (response0.statusCode == 200) { if (response0.statusCode == 200) {
final decodedResponse1 = jsonDecode(response0.body); final decodedResponse1 = jsonDecode(response0.body);
// Log.print('decodedResponse1: ${decodedResponse1}'); Log.print('decodedResponse1: ${decodedResponse1}');
final jwt = decodedResponse1['jwt']; final jwt = decodedResponse1['jwt'];
box.write(BoxName.jwt, X.c(X.c(X.c(jwt, cn), cC), cs)); box.write(BoxName.jwt, X.c(X.c(X.c(jwt, cn), cC), cs));
// await box.write(BoxName.hmac, decodedResponse1['hmac']); // await box.write(BoxName.hmac, decodedResponse1['hmac']);
await AppInitializer().getAIKey(Driver.keyOfApp);
await AppInitializer().getAIKey(Driver.initializationVector);
await Future.delayed(Duration.zero);
await EncryptionHelper.initialize();
await AppInitializer().getAIKey(Driver.payMobApikey); await AppInitializer().getAIKey(Driver.payMobApikey);
await AppInitializer().getAIKey(Driver.FCM_PRIVATE_KEY); await AppInitializer().getAIKey(Driver.FCM_PRIVATE_KEY);
await AppInitializer().getAIKey(Driver.initializationVector);
await AppInitializer().getAIKey(Driver.keyOfApp);
// ✅ بعد التأكد أن كل المفاتيح موجودة
await EncryptionHelper.initialize();
await AppInitializer().getKey(); await AppInitializer().getKey();
} else {} } else {}
} else { } else {

View File

@@ -44,7 +44,7 @@ class AccessTokenManager {
_accessToken = client.credentials.accessToken; _accessToken = client.credentials.accessToken;
_expiryDate = client.credentials.accessToken.expiry; _expiryDate = client.credentials.accessToken.expiry;
client.close(); client.close();
Log.print('_accessToken!.data: ${_accessToken!.data}'); // Log.print('_accessToken!.data: ${_accessToken!.data}');
return _accessToken!.data; return _accessToken!.data;
} catch (e) { } catch (e) {
throw Exception('Failed to obtain access token'); throw Exception('Failed to obtain access token');

View File

@@ -14,6 +14,7 @@ import '../../constant/box_name.dart';
import '../../constant/colors.dart'; import '../../constant/colors.dart';
import '../../constant/style.dart'; import '../../constant/style.dart';
import '../../main.dart'; import '../../main.dart';
import '../../print.dart';
import '../../views/auth/captin/criminal_documents_page.dart'; import '../../views/auth/captin/criminal_documents_page.dart';
import '../../views/home/Captin/home_captain/home_captin.dart'; import '../../views/home/Captin/home_captain/home_captin.dart';
import '../../views/home/Captin/orderCaptin/order_speed_request.dart'; import '../../views/home/Captin/orderCaptin/order_speed_request.dart';
@@ -180,6 +181,7 @@ class FirebaseMessagesController extends GetxController {
'Trip Cancelled. The cost of the trip will be added to your wallet.' 'Trip Cancelled. The cost of the trip will be added to your wallet.'
.tr, () { .tr, () {
box.write(BoxName.rideStatus, 'Cancel'); box.write(BoxName.rideStatus, 'Cancel');
Log.print('rideStatus from 184 : ${box.read(BoxName.rideStatus)}');
Get.offAll(HomeCaptain()); Get.offAll(HomeCaptain());
}); });
// cancelTripDialog1(); // cancelTripDialog1();
@@ -341,6 +343,8 @@ class FirebaseMessagesController extends GetxController {
title: 'Ok'.tr, title: 'Ok'.tr,
onPressed: () { onPressed: () {
box.write(BoxName.rideStatus, 'Cancel'); box.write(BoxName.rideStatus, 'Cancel');
Log.print(
'rideStatus from 347 : ${box.read(BoxName.rideStatus)}');
Get.offAll(HomeCaptain()); Get.offAll(HomeCaptain());
})); }));
} }
@@ -356,6 +360,8 @@ class FirebaseMessagesController extends GetxController {
title: 'Ok'.tr, title: 'Ok'.tr,
onPressed: () { onPressed: () {
box.write(BoxName.rideStatus, 'Cancel'); box.write(BoxName.rideStatus, 'Cancel');
Log.print(
'rideStatus from 364 : ${box.read(BoxName.rideStatus)}');
Get.offAll(HomeCaptain()); Get.offAll(HomeCaptain());
})); }));
} }
@@ -405,7 +411,7 @@ class FirebaseMessagesController extends GetxController {
Future<void> onInit() async { Future<void> onInit() async {
super.onInit(); super.onInit();
try { try {
var encryptedKey = await storage.read(key: 'FCM_PRIVATE_KEY'); var encryptedKey = await storage.read(key: BoxName.FCM_PRIVATE_KEY);
// Log.print('encryptedKey: ${encryptedKey}'); // Log.print('encryptedKey: ${encryptedKey}');
if (encryptedKey != null) { if (encryptedKey != null) {
serviceAccountKeyJson = serviceAccountKeyJson =
@@ -707,32 +713,39 @@ class FirebaseMessagesController extends GetxController {
if (response.statusCode == 200) { if (response.statusCode == 200) {
print( print(
'Notification sent successfully. Status code: ${response.statusCode}'); 'Notification sent successfully. Status code: ${response.statusCode}');
print('Response body: ${response.body}'); } else if (response.statusCode == 404) {
// Handle UNREGISTERED token
final responseBody = jsonDecode(response.body);
final errorCode = responseBody['error']['details']?[0]?['errorCode'];
if (errorCode == 'UNREGISTERED') {
print('Token is unregistered/invalid: $token');
// Remove token from your database
await removeInvalidToken(token);
return; // Don't retry for invalid tokens
}
} else { } else {
print( print(
'Failed to send notification. Status code: ${response.statusCode}'); 'Failed to send notification. Status code: ${response.statusCode}');
print('Response body: ${response.body}'); print('Response body: ${response.body}');
if (retryCount > 0) { if (retryCount > 0) {
print('Retrying... Attempts remaining: $retryCount'); print('Retrying... Attempts remaining: $retryCount');
await Future.delayed( await Future.delayed(const Duration(seconds: 2));
const Duration(seconds: 2)); // Optional delay before retrying return sendNotificationToDriverMAP(title, body, token, data, tone,
return sendNotificationToPassengerTokenCALL(
title, body, token, data, tone,
retryCount: retryCount - 1); retryCount: retryCount - 1);
} }
} }
} catch (e) { } catch (e) {
print('Error sending notification: $e'); // ... existing error handling ...
if (retryCount > 0) {
print('Retrying... Attempts remaining: $retryCount');
await Future.delayed(
const Duration(seconds: 2)); // Optional delay before retrying
return sendNotificationToPassengerTokenCALL(
title, body, token, data, tone,
retryCount: retryCount - 1);
} }
} }
Future<void> removeInvalidToken(String token) async {
// Remove token from your database/storage
// This prevents future attempts to send to invalid tokens
print('Removing invalid token from database: $token');
// Your database cleanup logic here
} }
} }

View File

@@ -522,7 +522,7 @@ class NotificationController extends GetxController {
if (data is String) { if (data is String) {
var orderData = jsonDecode(data); var orderData = jsonDecode(data);
if (orderData is List && orderData.length == 34) { if (orderData is List && orderData.length == 34) {
closeOverLay(); //closeOverLay();
Get.put(HomeCaptainController()).changeRideId(); Get.put(HomeCaptainController()).changeRideId();
Get.to(() => OrderRequestPage(), arguments: {'myListString': data}); Get.to(() => OrderRequestPage(), arguments: {'myListString': data});
} else { } else {
@@ -537,7 +537,7 @@ class NotificationController extends GetxController {
if (data is String) { if (data is String) {
var orderData = jsonDecode(data); var orderData = jsonDecode(data);
if (orderData is List && orderData.length == 34) { if (orderData is List && orderData.length == 34) {
closeOverLay(); //closeOverLay();
Get.put(HomeCaptainController()).changeRideId(); Get.put(HomeCaptainController()).changeRideId();
Get.to(() => OrderRequestPage(), arguments: {'myListString': data}); Get.to(() => OrderRequestPage(), arguments: {'myListString': data});
} else { } else {
@@ -550,7 +550,7 @@ class NotificationController extends GetxController {
void _handleADSNotification() { void _handleADSNotification() {
// var orderData = jsonDecode(data); // var orderData = jsonDecode(data);
closeOverLay(); //closeOverLay();
Get.to( Get.to(
() => const NotificationCaptain(), () => const NotificationCaptain(),
); );

View File

@@ -94,9 +94,9 @@ class CRUD {
'X-HMAC-Auth': hmac.toString(), 'X-HMAC-Auth': hmac.toString(),
}, },
); );
Log.print('response.request: ${response.request}'); // Log.print('response.request: ${response.request}');
Log.print('response.body: ${response.body}'); // Log.print('response.body: ${response.body}');
print(payload); // print(payload);
if (response.statusCode == 200) { if (response.statusCode == 200) {
var jsonData = jsonDecode(response.body); var jsonData = jsonDecode(response.body);
if (jsonData['status'] == 'success') { if (jsonData['status'] == 'success') {
@@ -128,11 +128,13 @@ class CRUD {
Future<dynamic> postWallet( Future<dynamic> postWallet(
{required String link, Map<String, dynamic>? payload}) async { {required String link, Map<String, dynamic>? payload}) async {
var s = await LoginDriverController().getJwtWallet(); var s = await LoginDriverController().getJwtWallet();
// Log.print('jwt: ${s}');
final hmac = box.read(BoxName.hmac); final hmac = box.read(BoxName.hmac);
Log.print('hmac: ${hmac}'); // Log.print('hmac: ${hmac}');
var url = Uri.parse(link); var url = Uri.parse(link);
// Log.print('url: ${url}');
try { try {
await LoginDriverController().getJWT(); // await LoginDriverController().getJWT();
var response = await http.post( var response = await http.post(
url, url,
@@ -143,9 +145,9 @@ class CRUD {
'X-HMAC-Auth': hmac.toString(), 'X-HMAC-Auth': hmac.toString(),
}, },
); );
print(response.request); // Log.print('response.request:${response.request}');
Log.print('response.body: ${response.body}'); // Log.print('response.body: ${response.body}');
print(payload); // Log.print('payload:$payload');
if (response.statusCode == 200) { if (response.statusCode == 200) {
try { try {
var jsonData = jsonDecode(response.body); var jsonData = jsonDecode(response.body);
@@ -201,9 +203,9 @@ class CRUD {
// 'Authorization': 'Bearer ${box.read(BoxName.jwt)}' // 'Authorization': 'Bearer ${box.read(BoxName.jwt)}'
}, },
); );
print(response.request); // print(response.request);
Log.print('response.body: ${response.body}'); // Log.print('response.body: ${response.body}');
print(payload); // print(payload);
if (response.statusCode == 200) { if (response.statusCode == 200) {
try { try {
var jsonData = jsonDecode(response.body); var jsonData = jsonDecode(response.body);
@@ -439,22 +441,46 @@ class CRUD {
} }
} }
sendEmail( Future<void> sendEmail(String link, Map<String, String>? payload) async {
String link, // التحقق من صلاحية التوكن
Map<String, String>? payload, String rawJwt = box.read(BoxName.jwt);
) async { String token = X
var headers = { .r(X.r(X.r(rawJwt, cn), cC), cs)
.toString()
.split(AppInformation.addd)[0];
bool isTokenExpired = JwtDecoder.isExpired(token);
if (isTokenExpired) {
await LoginDriverController().getJWT();
rawJwt = box.read(BoxName.jwt); // تحديث التوكن بعد التجديد
token = X
.r(X.r(X.r(rawJwt, cn), cC), cs)
.toString()
.split(AppInformation.addd)[0];
}
// إعداد الهيدر
final headers = {
"Content-Type": "application/x-www-form-urlencoded", "Content-Type": "application/x-www-form-urlencoded",
'Authorization': "Authorization": "Bearer $token",
'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials))}',
}; };
var request = http.Request('POST', Uri.parse(link));
request.bodyFields = payload!; // إعداد الطلب
final request = http.Request('POST', Uri.parse(link));
request.bodyFields = payload ?? {};
request.headers.addAll(headers); request.headers.addAll(headers);
http.StreamedResponse response = await request.send(); // إرسال الطلب
final response = await request.send();
// التحقق من النتيجة
if (response.statusCode == 200) { if (response.statusCode == 200) {
} else {} print("✅ Email sent successfully.");
} else {
print("❌ Failed to send email. Status: ${response.statusCode}");
final responseBody = await response.stream.bytesToString();
print("Response body: $responseBody");
}
} }
Future<dynamic> postFromDialogue({ Future<dynamic> postFromDialogue({

View File

@@ -105,7 +105,7 @@ class AI extends GetxController {
NotificationController().showNotification( NotificationController().showNotification(
"Code approved".tr, "Code approved".tr, 'tone2', ''); "Code approved".tr, "Code approved".tr, 'tone2', '');
// Notification text with dynamic token // Notification text with dynamic token
FirebaseMessagesController().sendNotificationToDriverMAP( Get.put(FirebaseMessagesController()).sendNotificationToDriverMAP(
'You have received a gift token!'.tr, 'You have received a gift token!'.tr,
'for '.tr + box.read(BoxName.phoneDriver).toString(), 'for '.tr + box.read(BoxName.phoneDriver).toString(),
jsonDecode(res)['message'][0]['token'].toString(), jsonDecode(res)['message'][0]['token'].toString(),

View File

@@ -133,8 +133,8 @@ class LocationController extends GetxController {
// ✅ إدخال للسيرفر كل دقيقة // ✅ إدخال للسيرفر كل دقيقة
_insertCounter++; _insertCounter++;
Log.print('_insertCounter: ${_insertCounter}'); // Log.print('_insertCounter: ${_insertCounter}');
if (_insertCounter >= 12) { if (_insertCounter == 12) {
_insertCounter = 0; _insertCounter = 0;
await CRUD().post( await CRUD().post(
link: box.read(BoxName.serverChosen) + '/ride/location/add.php', link: box.read(BoxName.serverChosen) + '/ride/location/add.php',

View File

@@ -247,15 +247,15 @@ class SecurityHelper {
await box.write('isTampered', isTampered); // Use await await box.write('isTampered', isTampered); // Use await
await box.write('isJailBroken', isJailBroken); // Use await await box.write('isJailBroken', isJailBroken); // Use await
debugPrint("Security Check Results:"); // debugPrint("Security Check Results:");
debugPrint("isNotTrust: $isNotTrust"); // debugPrint("isNotTrust: $isNotTrust");
debugPrint("isJailBroken: $isJailBroken"); // debugPrint("isJailBroken: $isJailBroken");
debugPrint("isRealDevice: $isRealDevice"); // debugPrint("isRealDevice: $isRealDevice");
debugPrint("isOnExternalStorage: $isOnExternalStorage"); // debugPrint("isOnExternalStorage: $isOnExternalStorage");
debugPrint("checkForIssues: $checkForIssues"); // debugPrint("checkForIssues: $checkForIssues");
debugPrint("isDevMode: $isDevMode"); // debugPrint("isDevMode: $isDevMode");
debugPrint("isTampered: $isTampered"); // debugPrint("isTampered: $isTampered");
debugPrint("Bundle ID: $bundleId"); // Print the bundle ID // debugPrint("Bundle ID: $bundleId"); // Print the bundle ID
// Check for security risks and potentially show a warning // Check for security risks and potentially show a warning
if (isJailBroken || isRealDevice == false || isTampered) { if (isJailBroken || isRealDevice == false || isTampered) {

View File

@@ -40,7 +40,6 @@ class AppInitializer {
Future<void> initializeApp() async { Future<void> initializeApp() async {
if (box.read(BoxName.jwt) == null) { if (box.read(BoxName.jwt) == null) {
Log.print('box.read(BoxName.jwt): ${box.read(BoxName.jwt)}');
await LoginDriverController().getJWT(); await LoginDriverController().getJWT();
} else { } else {
bool isTokenExpired = JwtDecoder.isExpired(X bool isTokenExpired = JwtDecoder.isExpired(X
@@ -55,15 +54,18 @@ class AppInitializer {
// await getKey(); // await getKey();
} }
getAIKey(String key1) async { Future<void> getAIKey(String key1) async {
if (box.read(BoxName.firstTimeLoadKey) == null) {
var res = var res =
await CRUD().get(link: AppLink.getapiKey, payload: {"keyName": key1}); await CRUD().get(link: AppLink.getapiKey, payload: {"keyName": key1});
if (res != 'failure') { if (res != 'failure') {
var d = jsonDecode(res)['message']; var d = jsonDecode(res)['message'];
await storage.write(key: key1, value: d[key1].toString()); final rawValue = d[key1].toString();
// ✅ اكتبها في storage
await storage.write(key: key1, value: rawValue);
await Future.delayed(Duration.zero); await Future.delayed(Duration.zero);
} else {}
} }
} }

View File

@@ -12,8 +12,10 @@ import '../../../constant/links.dart';
import '../../../constant/style.dart'; import '../../../constant/style.dart';
import '../../../constant/table_names.dart'; import '../../../constant/table_names.dart';
import '../../../main.dart'; import '../../../main.dart';
import '../../../print.dart';
import '../../../views/home/my_wallet/walet_captain.dart'; import '../../../views/home/my_wallet/walet_captain.dart';
import '../../../views/widgets/elevated_btn.dart'; import '../../../views/widgets/elevated_btn.dart';
import '../../firebase/firbase_messge.dart';
import '../../functions/crud.dart'; import '../../functions/crud.dart';
import '../../functions/location_background_controller.dart'; import '../../functions/location_background_controller.dart';
import '../../functions/location_controller.dart'; import '../../functions/location_controller.dart';
@@ -264,7 +266,7 @@ class HomeCaptainController extends GetxController {
@override @override
void onInit() async { void onInit() async {
// await locationBackController.requestLocationPermission(); // await locationBackController.requestLocationPermission();
Get.put(FirebaseMessagesController());
addToken(); addToken();
await getlocation(); await getlocation();
onButtonSelected(); onButtonSelected();
@@ -429,6 +431,7 @@ class HomeCaptainController extends GetxController {
void changeToAppliedRide(String status) { void changeToAppliedRide(String status) {
box.write(BoxName.rideStatus, status); box.write(BoxName.rideStatus, status);
Log.print('rideStatus from homcaptain : ${box.read(BoxName.rideStatus)}');
update(); update();
} }

View File

@@ -25,6 +25,7 @@ import '../../firebase/firbase_messge.dart';
import '../../functions/crud.dart'; import '../../functions/crud.dart';
import '../../functions/encrypt_decrypt.dart'; import '../../functions/encrypt_decrypt.dart';
import '../../functions/location_controller.dart'; import '../../functions/location_controller.dart';
import '../../functions/tts.dart';
class MapDriverController extends GetxController { class MapDriverController extends GetxController {
bool isLoading = true; bool isLoading = true;
@@ -174,7 +175,7 @@ class MapDriverController extends GetxController {
cancelTripFromDriverAfterApplied() async { cancelTripFromDriverAfterApplied() async {
if (formKeyCancel.currentState!.validate()) { if (formKeyCancel.currentState!.validate()) {
box.write(BoxName.statusDriverLocation, 'off'); box.write(BoxName.statusDriverLocation, 'off');
FirebaseMessagesController().sendNotificationToDriverMAP( Get.find<FirebaseMessagesController>().sendNotificationToDriverMAP(
"Cancel Trip from driver", "Cancel Trip from driver",
"Trip Cancelled from driver. We are looking for a new driver. Please wait." "Trip Cancelled from driver. We are looking for a new driver. Please wait."
.tr, .tr,
@@ -235,6 +236,8 @@ class MapDriverController extends GetxController {
'created_at': DateTime.now().toString(), 'created_at': DateTime.now().toString(),
'driver_id': box.read(BoxName.driverID).toString(), 'driver_id': box.read(BoxName.driverID).toString(),
}, TableName.driverOrdersRefuse); }, TableName.driverOrdersRefuse);
box.write(BoxName.rideStatus, 'Cancel');
Log.print('rideStatus from map 240 : ${box.read(BoxName.rideStatus)}');
Get.find<HomeCaptainController>().getRefusedOrderByCaptain(); Get.find<HomeCaptainController>().getRefusedOrderByCaptain();
Get.offAll(() => HomeCaptain()); Get.offAll(() => HomeCaptain());
} }
@@ -242,6 +245,7 @@ class MapDriverController extends GetxController {
void startTimerToShowPassengerInfoWindowFromDriver() async { void startTimerToShowPassengerInfoWindowFromDriver() async {
if (box.read(BoxName.rideStatus) == 'Begin') { if (box.read(BoxName.rideStatus) == 'Begin') {
Log.print('rideStatus from map 248 : ${box.read(BoxName.rideStatus)}');
isPassengerInfoWindow = false; isPassengerInfoWindow = false;
} else { } else {
isPassengerInfoWindow = true; isPassengerInfoWindow = true;
@@ -298,6 +302,7 @@ class MapDriverController extends GetxController {
void driverGoToPassenger() async { void driverGoToPassenger() async {
changeRideToBeginToPassenger(); changeRideToBeginToPassenger();
box.write(BoxName.rideStatus, 'Applied'); box.write(BoxName.rideStatus, 'Applied');
Log.print('rideStatus from map 304 : ${box.read(BoxName.rideStatus)}');
update(); update();
await CRUD().post( await CRUD().post(
link: "${AppLink.seferCairoServer}/ride/rides/update.php", link: "${AppLink.seferCairoServer}/ride/rides/update.php",
@@ -315,7 +320,7 @@ class MapDriverController extends GetxController {
} }
// Get.find<HomeCaptainController>().changeToAppliedRide('Applied'); // Get.find<HomeCaptainController>().changeToAppliedRide('Applied');
FirebaseMessagesController().sendNotificationToDriverMAP( Get.find<FirebaseMessagesController>().sendNotificationToDriverMAP(
'Driver Is Going To Passenger'.tr, 'Driver Is Going To Passenger'.tr,
box.read(BoxName.nameDriver).toString(), //todo name driver box.read(BoxName.nameDriver).toString(), //todo name driver
tokenPassenger, tokenPassenger,
@@ -392,6 +397,7 @@ class MapDriverController extends GetxController {
// todo ride details // todo ride details
// Get.find<HomeCaptainController>().changeToAppliedRide('Begin'); // Get.find<HomeCaptainController>().changeToAppliedRide('Begin');
box.write(BoxName.rideStatus, 'Begin'); box.write(BoxName.rideStatus, 'Begin');
Log.print('rideStatus from map 399 : ${box.read(BoxName.rideStatus)}');
// Get.find<HomeCaptainController>().update(); // Get.find<HomeCaptainController>().update();
update(); update();
await CRUD().post(link: AppLink.updateRides, payload: { await CRUD().post(link: AppLink.updateRides, payload: {
@@ -418,7 +424,7 @@ class MapDriverController extends GetxController {
'status': 'Begin' 'status': 'Begin'
}); });
} }
FirebaseMessagesController().sendNotificationToDriverMAP( Get.find<FirebaseMessagesController>().sendNotificationToDriverMAP(
'Trip is Begin'.tr, 'Trip is Begin'.tr,
box.read(BoxName.nameDriver).toString(), box.read(BoxName.nameDriver).toString(),
tokenPassenger, tokenPassenger,
@@ -584,17 +590,29 @@ class MapDriverController extends GetxController {
} }
} }
void finishRideFromDriver() { Future<void> finishRideFromDriver() async {
double distanceToDestination = Geolocator.distanceBetween( double distanceToDestination = Geolocator.distanceBetween(
latLngPassengerLocation.latitude, latLngPassengerDestination.latitude,
latLngPassengerLocation.longitude, latLngPassengerDestination.longitude,
Get.find<LocationController>().myLocation.latitude, Get.find<LocationController>().myLocation.latitude,
Get.find<LocationController>().myLocation.longitude, Get.find<LocationController>().myLocation.longitude,
); );
final originalDistanceM = double.parse(distance.toString()) * 1000;
if (distanceToDestination > (double.parse(distance.toString()) / 3)) { // 2. احسب المسافة التي قطعها السائق حتى الآن
Log.print('distanceToDestination: ${distanceToDestination}'); final movedDistanceM = originalDistanceM - distanceToDestination;
// 3. عتبة ثلث المسافة
final oneThirdDistanceM = originalDistanceM / 3;
// Logging للتتبع
Log.print('originalDistanceM: $originalDistanceM');
Log.print('distanceToDestinationM: $distanceToDestination');
Log.print('movedDistanceM: $movedDistanceM');
Log.print('oneThirdDistanceM: $oneThirdDistanceM');
// 4. إذا لم يقطع السائق ثلث المسافة، نعرض التأكيد
if (movedDistanceM < oneThirdDistanceM) {
MyDialog().getDialog( MyDialog().getDialog(
'Are you sure to exit ride?'.tr, 'Are you sure to exit ride?'.tr,
'', '',
@@ -603,33 +621,39 @@ class MapDriverController extends GetxController {
finishRideFromDriver1(); finishRideFromDriver1();
}, },
); );
} else { } /////
else {
final textToSpeechController = Get.put(TextToSpeechController());
MyDialog().getDialog( MyDialog().getDialog(
"You haven't moved sufficiently!".tr, "You haven't moved sufficiently!".tr,
'', '',
() => Get.back(), () => Get.back(),
); );
await textToSpeechController
.speakText("You haven't moved sufficiently!".tr);
} }
} }
String paymentToken = ''; String paymentToken = '';
Future<String> generateTokenDriver(String amount) async { Future<String> generateTokenDriver(String amount) async {
var res = await CRUD().post(link: AppLink.addPaymentTokenDriver, payload: { var res =
await CRUD().postWallet(link: AppLink.addPaymentTokenDriver, payload: {
'driverID': box.read(BoxName.driverID).toString(), 'driverID': box.read(BoxName.driverID).toString(),
'amount': amount.toString(), 'amount': amount.toString(),
}); });
var d = jsonDecode(res); var d = (res);
return d['message']; return d['message'];
} }
String paymentTokenPassenger = ''; String paymentTokenPassenger = '';
Future<String> generateTokenPassenger(String amount) async { Future<String> generateTokenPassenger(String amount) async {
var res = var res = await CRUD()
await CRUD().post(link: AppLink.addPaymentTokenPassenger, payload: { .postWallet(link: AppLink.addPaymentTokenPassenger, payload: {
'passengerId': passengerId, 'passengerId': passengerId,
'amount': amount.toString(), 'amount': amount.toString(),
}); });
var d = jsonDecode(res); var d = (res);
return d['message']; return d['message'];
} }
@@ -638,6 +662,7 @@ class MapDriverController extends GetxController {
isRideStarted = false; isRideStarted = false;
isPriceWindow = false; isPriceWindow = false;
box.write(BoxName.rideStatus, 'Finished'); box.write(BoxName.rideStatus, 'Finished');
Log.print('rideStatus from map 664 : ${box.read(BoxName.rideStatus)}');
// Calculate totalCost more concisely // Calculate totalCost more concisely
if (price < 20) { if (price < 20) {
@@ -699,7 +724,8 @@ class MapDriverController extends GetxController {
if (walletChecked == 'true') { if (walletChecked == 'true') {
paymentToken = await generateTokenPassenger( paymentToken = await generateTokenPassenger(
((-1) * double.parse(paymentAmount)).toString()); ((-1) * double.parse(paymentAmount)).toString());
futures.add(CRUD().post(link: AppLink.addPassengersWallet, payload: { futures
.add(CRUD().postWallet(link: AppLink.addPassengersWallet, payload: {
'passenger_id': (passengerId), 'passenger_id': (passengerId),
'balance': ((-1) * double.parse(paymentAmount)).toString(), 'balance': ((-1) * double.parse(paymentAmount)).toString(),
'token': paymentToken, 'token': paymentToken,
@@ -707,7 +733,7 @@ class MapDriverController extends GetxController {
} }
paymentToken = await generateTokenDriver(paymentAmount.toString()); paymentToken = await generateTokenDriver(paymentAmount.toString());
futures.add(CRUD().post(link: AppLink.addDrivePayment, payload: { futures.add(CRUD().postWallet(link: AppLink.addDrivePayment, payload: {
'rideId': (rideId), 'rideId': (rideId),
'amount': paymentAmount, 'amount': paymentAmount,
'payment_method': 'payment_method':
@@ -720,7 +746,8 @@ class MapDriverController extends GetxController {
if (double.parse(passengerWalletBurc) < 0) { if (double.parse(passengerWalletBurc) < 0) {
final paymentToken1 = await generateTokenPassenger( final paymentToken1 = await generateTokenPassenger(
((-1) * double.parse(passengerWalletBurc)).toString()); ((-1) * double.parse(passengerWalletBurc)).toString());
futures.add(CRUD().post(link: AppLink.addPassengersWallet, payload: { futures
.add(CRUD().postWallet(link: AppLink.addPassengersWallet, payload: {
'passenger_id': (passengerId), 'passenger_id': (passengerId),
'token': paymentToken1, 'token': paymentToken1,
'balance': ((-1) * double.parse(passengerWalletBurc)).toString() 'balance': ((-1) * double.parse(passengerWalletBurc)).toString()
@@ -730,7 +757,8 @@ class MapDriverController extends GetxController {
double pointsSubtraction = double.parse(paymentAmount) * (-1) * 0.08; double pointsSubtraction = double.parse(paymentAmount) * (-1) * 0.08;
final paymentToken2 = final paymentToken2 =
await generateTokenDriver((pointsSubtraction).toStringAsFixed(0)); await generateTokenDriver((pointsSubtraction).toStringAsFixed(0));
futures.add(CRUD().post(link: AppLink.addDriversWalletPoints, payload: { futures
.add(CRUD().postWallet(link: AppLink.addDriversWalletPoints, payload: {
'paymentID': 'rideId${(rideId)}', 'paymentID': 'rideId${(rideId)}',
'amount': (pointsSubtraction).toStringAsFixed(0), 'amount': (pointsSubtraction).toStringAsFixed(0),
'paymentMethod': paymentMethod, 'paymentMethod': paymentMethod,
@@ -743,7 +771,7 @@ class MapDriverController extends GetxController {
Get.put(DriverBehaviorController()).sendSummaryToServer(driverId, rideId); Get.put(DriverBehaviorController()).sendSummaryToServer(driverId, rideId);
// Send notification (this likely depends on previous steps) // Send notification (this likely depends on previous steps)
FirebaseMessagesController().sendNotificationToDriverMAP( Get.find<FirebaseMessagesController>().sendNotificationToDriverMAP(
"Driver Finish Trip".tr, "Driver Finish Trip".tr,
'${'you will pay to Driver'.tr} $paymentAmount \$', '${'you will pay to Driver'.tr} $paymentAmount \$',
tokenPassenger, tokenPassenger,
@@ -862,7 +890,7 @@ class MapDriverController extends GetxController {
// 'driverID': box.read(BoxName.driverID).toString(), // 'driverID': box.read(BoxName.driverID).toString(),
// }); // });
// Future.delayed(const Duration(milliseconds: 300)); // Future.delayed(const Duration(milliseconds: 300));
// FirebaseMessagesController().sendNotificationToDriverMAP( // Get.find<FirebaseMessagesController>().sendNotificationToDriverMAP(
// "Driver Finish Trip".tr, // "Driver Finish Trip".tr,
// '${'you will pay to Driver'.tr} $paymentAmount \$', // '${'you will pay to Driver'.tr} $paymentAmount \$',
// tokenPassenger, // tokenPassenger,
@@ -1362,7 +1390,8 @@ class MapDriverController extends GetxController {
void onInit() async { void onInit() async {
mapAPIKEY = await storage.read(key: BoxName.mapAPIKEY); mapAPIKEY = await storage.read(key: BoxName.mapAPIKEY);
// Get the passenger location from the arguments. // Get the passenger location from the arguments.
// await argumentLoading(); await argumentLoading();
Get.put(FirebaseMessagesController());
runGoogleMapDirectly(); runGoogleMapDirectly();
addCustomCarIcon(); addCustomCarIcon();
addCustomPassengerIcon(); addCustomPassengerIcon();

View File

@@ -82,7 +82,7 @@ class CaptainWalletController extends GetxController {
//get new driver details //get new driver details
isNewTransfer = true; isNewTransfer = true;
update(); update();
var res = await CRUD().getWallet( var res = await CRUD().get(
link: AppLink.getDriverDetails, link: AppLink.getDriverDetails,
payload: {'driver_phone': '+2${newDriverPhoneController.text}'}); payload: {'driver_phone': '+2${newDriverPhoneController.text}'});
isNewTransfer = false; isNewTransfer = false;
@@ -155,7 +155,7 @@ class CaptainWalletController extends GetxController {
'driverID': box.read(BoxName.driverID).toString(), 'driverID': box.read(BoxName.driverID).toString(),
'amount': amount.toString(), 'amount': amount.toString(),
}); });
var d = jsonDecode(res); var d = (res);
return d['message']; return d['message'];
} }
@@ -168,14 +168,14 @@ class CaptainWalletController extends GetxController {
'amount': amount.toString(), 'amount': amount.toString(),
'payment_method': paymentMethod.toString(), 'payment_method': paymentMethod.toString(),
}); });
var d = jsonDecode(res); var d = (res);
// paymentID = d['message'].toString(); // paymentID = d['message'].toString();
return d['message']; return d['message'];
} }
Future addDriverWallet(String paymentMethod, point, count) async { Future addDriverWallet(String paymentMethod, point, count) async {
paymentToken = await generateToken(count); paymentToken = await generateToken(count);
var paymentID = await getPaymentId(paymentMethod, point); var paymentID = await getPaymentId(paymentMethod, point.toString());
await CRUD().postWallet(link: AppLink.addDriversWalletPoints, payload: { await CRUD().postWallet(link: AppLink.addDriversWalletPoints, payload: {
'driverID': box.read(BoxName.driverID).toString(), 'driverID': box.read(BoxName.driverID).toString(),
'paymentID': paymentID.toString(), 'paymentID': paymentID.toString(),
@@ -245,7 +245,8 @@ class CaptainWalletController extends GetxController {
'payment_method': paymentMethod.toString(), 'payment_method': paymentMethod.toString(),
'passengerID': paymentMethod, 'passengerID': paymentMethod,
}); });
await addSeferWallet(paymentMethod, (double.parse(point) * -1).toString()); await addSeferWallet(paymentMethod,
(double.parse(point) * -2).toString()); // deduct 2 from sefer wallet
} }
Future addSeferWallet(String paymentMethod, String point) async { Future addSeferWallet(String paymentMethod, String point) async {
@@ -290,7 +291,7 @@ class CaptainWalletController extends GetxController {
'paymentMethod': paymentMethod2.toString(), 'paymentMethod': paymentMethod2.toString(),
}); });
if (res1 != 'failure') { if (res1 != 'failure') {
FirebaseMessagesController().sendNotificationToDriverMAP( Get.find<FirebaseMessagesController>().sendNotificationToDriverMAP(
'Transfer', 'Transfer',
'${'You have transfer to your wallet from'.tr}' '${'You have transfer to your wallet from'.tr}'
'${box.read(BoxName.nameDriver)}', '${box.read(BoxName.nameDriver)}',

View File

@@ -1,15 +1,12 @@
import 'dart:convert'; import 'dart:convert';
import 'package:local_auth/local_auth.dart'; import 'package:local_auth/local_auth.dart';
import 'package:sefer_driver/constant/api_key.dart';
import 'package:sefer_driver/constant/box_name.dart'; import 'package:sefer_driver/constant/box_name.dart';
import 'package:sefer_driver/main.dart'; import 'package:sefer_driver/main.dart';
import 'package:sefer_driver/views/widgets/error_snakbar.dart'; import 'package:sefer_driver/views/widgets/error_snakbar.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:secure_string_operations/secure_string_operations.dart';
import '../../../constant/char_map.dart';
import '../../../constant/links.dart'; import '../../../constant/links.dart';
import '../../../views/widgets/mydialoug.dart'; import '../../../views/widgets/mydialoug.dart';
import '../../functions/crud.dart'; import '../../functions/crud.dart';
@@ -19,39 +16,8 @@ class PaymobPayout extends GetxController {
bool isLoading = false; bool isLoading = false;
String dropdownValue = 'etisalat'; String dropdownValue = 'etisalat';
Future<String> getToken() async {
var headers = {
'Content-Type': 'application/x-www-form-urlencoded',
// 'Cookie':
// 'csrftoken=74iZJ8XYyuTm5WRq2W4tpWX5eqoJLZVK5QhuDrChWpDtzpgGA269bbCWuEcW85t4'
};
var payMobOutClientSecrret =
X.r(X.r(X.r(await getAIKey(KN.pmobsec), cn), cC), cs);
var payMobOutClientId =
X.r(X.r(X.r(await getAIKey(KN.pmobid), cn), cC), cs);
var body = {
'grant_type': 'password',
'username': AK.payMobOutUserName,
'password': AK.payMobOutPassword,
'client_id': payMobOutClientId,
'client_secret': payMobOutClientSecrret
};
var res = await http.post(
Uri.parse('https://payouts.paymobsolutions.com/api/secure/o/token/'),
headers: headers,
body: body,
);
String token = '';
if (res.statusCode == 200) {
var decode = jsonDecode(res.body);
token = decode['access_token'];
}
return token;
}
int payOutFee = 5; int payOutFee = 5;
payToDriverWallet( payToDriverWallet(String amount, String issuer, String msisdn) async {
String token, String amount, String issuer, String msisdn) async {
bool isAvailable = await LocalAuthentication().isDeviceSupported(); bool isAvailable = await LocalAuthentication().isDeviceSupported();
if (isAvailable) { if (isAvailable) {
// Authenticate the user // Authenticate the user
@@ -62,21 +28,18 @@ class PaymobPayout extends GetxController {
sensitiveTransaction: true, sensitiveTransaction: true,
)); ));
if (didAuthenticate) { if (didAuthenticate) {
var headers = { var dec = await CRUD().postWallet(
'Authorization': 'Bearer $token', link:
'Content-Type': 'application/json', 'wl.tripz-egypt.com/v1/main/ride/payMob/paymob_driver/paymob_payout.php',
}; payload: {
var body = json.encode({ "issuer": issuer,
"amount": amount, //"10.00", "method": "wallet",
"issuer": issuer, //"vodafone", "amount": amount, //9.0,
"msisdn": msisdn, // "01023456789" "full_name":
'${box.read(BoxName.nameDriver)} ${box.read(BoxName.lastNameDriver)}',
"msisdn": msisdn, //"01010101010",
"bank_transaction_type": "cash_transfer"
}); });
var res = await http.post(
Uri.parse('https://payouts.paymobsolutions.com/api/secure/disburse/'),
headers: headers,
body: body,
);
var dec = jsonDecode(res.body);
if (dec['disbursement_status'] == 'successful') { if (dec['disbursement_status'] == 'successful') {
var paymentToken = await Get.find<CaptainWalletController>() var paymentToken = await Get.find<CaptainWalletController>()
.generateToken( .generateToken(
@@ -149,8 +112,8 @@ class PaymobPayout extends GetxController {
} else {} } else {}
} }
payToDriverBankAccount(String token, String amount, String bankCardNumber, payToDriverBankAccount(
String bankCode) async { String amount, String bankCardNumber, String bankCode) async {
bool isAvailable = await LocalAuthentication().isDeviceSupported(); bool isAvailable = await LocalAuthentication().isDeviceSupported();
if (isAvailable) { if (isAvailable) {
// Authenticate the user // Authenticate the user
@@ -161,12 +124,9 @@ class PaymobPayout extends GetxController {
sensitiveTransaction: true, sensitiveTransaction: true,
)); ));
if (didAuthenticate) { if (didAuthenticate) {
var headers = {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
};
var body = { var body = {
"issuer": "bank_card", "issuer": "bank_card",
"method": "bank_card",
"amount": amount, //9.0, "amount": amount, //9.0,
"full_name": "full_name":
'${box.read(BoxName.nameDriver)} ${box.read(BoxName.lastNameDriver)}', '${box.read(BoxName.nameDriver)} ${box.read(BoxName.lastNameDriver)}',
@@ -174,12 +134,11 @@ class PaymobPayout extends GetxController {
"bank_code": bankCode, //"CIB", "bank_code": bankCode, //"CIB",
"bank_transaction_type": "cash_transfer" "bank_transaction_type": "cash_transfer"
}; };
var res = await http.post( var dec = await CRUD().postWallet(
Uri.parse('https://payouts.paymobsolutions.com/api/secure/disburse/'), link:
headers: headers, 'wl.tripz-egypt.com/v1/main/ride/payMob/paymob_driver/paymob_payout.php',
body: body, payload: body,
); );
var dec = jsonDecode(res.body);
if (dec['disbursement_status'] == 'successful') { if (dec['disbursement_status'] == 'successful') {
var paymentToken = await Get.find<CaptainWalletController>() var paymentToken = await Get.find<CaptainWalletController>()
.generateToken( .generateToken(
@@ -236,8 +195,7 @@ class PaymobPayout extends GetxController {
sensitiveTransaction: true, sensitiveTransaction: true,
)); ));
if (didAuthenticate) { if (didAuthenticate) {
String token = await getToken(); await payToDriverWallet(amount, issuer, msisdn);
await payToDriverWallet(token, amount, issuer, msisdn);
} else { } else {
MyDialog().getDialog('Authentication failed'.tr, ''.tr, () { MyDialog().getDialog('Authentication failed'.tr, ''.tr, () {
Get.back(); Get.back();
@@ -263,8 +221,7 @@ class PaymobPayout extends GetxController {
sensitiveTransaction: true, sensitiveTransaction: true,
)); ));
if (didAuthenticate) { if (didAuthenticate) {
String token = await getToken(); await payToDriverBankAccount(amount, bankCardNumber, bankCode);
await payToDriverBankAccount(token, amount, bankCardNumber, bankCode);
} else { } else {
MyDialog().getDialog('Authentication failed'.tr, ''.tr, () { MyDialog().getDialog('Authentication failed'.tr, ''.tr, () {
Get.back(); Get.back();

View File

@@ -65,6 +65,17 @@ class MyTranslation extends Translations {
"Order Applied": "تم تطبيق الطلب", "Order Applied": "تم تطبيق الطلب",
//firebase above //firebase above
"payment_success": "تمت العملية بنجاح",
"transaction_id": "رقم العملية",
"amount_paid": "المبلغ المدفوع",
"bonus_added": "البونص المضاف",
"points": "نقطة",
"transaction_failed": "فشل العملية",
"connection_failed": "فشل الاتصال",
"server_error": "خطأ في الخادم",
"server_error_message": "حدث خطأ أثناء الاتصال بالخادم",
"cancel": "إلغاء", "Syria": "‏سوريا", "cancel": "إلغاء", "Syria": "‏سوريا",
"Security Warning": "تحذير أمني", "Security Warning": "تحذير أمني",
"Potential security risks detected. The application will close in @seconds seconds.": "Potential security risks detected. The application will close in @seconds seconds.":
@@ -75,7 +86,28 @@ class MyTranslation extends Translations {
"Security Warning": "⚠️ تحذير أمني", "Security Warning": "⚠️ تحذير أمني",
"Potential security risks detected. The application may not function correctly.": "Potential security risks detected. The application may not function correctly.":
"تم اكتشاف ثغرات أمنية على هذا الجهاز. للحفاظ على أمان بياناتك، سيتم حذف جميع البيانات وإغلاق التطبيق.", "تم اكتشاف ثغرات أمنية على هذا الجهاز. للحفاظ على أمان بياناتك، سيتم حذف جميع البيانات وإغلاق التطبيق.",
"How to use Tripz": "كيفية استخدام Tripz",
"What are the order details we provide to you?":
"ما هي تفاصيل الطلب التي نوفرها لك؟",
"Tripz Wallet Features:\n\nTransfer money multiple times.\nTransfer to anyone.\nMake purchases.\nCharge your account.\nCharge a friend's Tripz account.\nStore your money with us and receive it in your bank as a monthly salary.":
"ميزات محفظة Tripz:\n\nتحويل الأموال عدة مرات.\nالتحويل إلى أي شخص.\nإجراء عمليات شراء.\nشحن حسابك.\nشحن حساب Tripz لصديق.\nقم بتخزين أموالك معنا واستلامها في بنكك كراتب شهري.",
"What is the feature of our wallet?": "ما هي مميزات محفظتنا؟",
"What is Types of Trips in Tripz?": "ما هي أنواع الرحلات في Tripz؟",
'''Types of Trips in Tripz:
Comfort: For cars newer than 2017 with air conditioning.
Lady: For girl drivers.
Speed: For fixed salary and endpoints.
Mashwari: For flexible trips where passengers choose the car and driver with prior arrangements.
Raih Gai: For same-day return trips longer than 50km.
''': """أنواع الرحلات في Tripz:
راحة: للسيارات الأحدث من 2017 مع تكييف الهواء.
للسائقات الإناث.
سبيد: براتب ثابت ونقاط نهاية محددة.
مشاوير: للرحلات المرنة حيث يختار الركاب السيارة والسائق باتفاق مسبق.
رحّي غاي: للرحلات ذات العودة في نفس اليوم التي تزيد عن 50 كم.
""",
"I will go now": "هروح دلوقتي", "I will go now": "هروح دلوقتي",
"Yes": "أيوة", "Yes": "أيوة",
"No,I want": "لا، أنا عاوز", "No,I want": "لا، أنا عاوز",

View File

@@ -67,7 +67,7 @@ class RateController extends GetxController {
'driverID': box.read(BoxName.driverID).toString(), 'driverID': box.read(BoxName.driverID).toString(),
}); });
FirebaseMessagesController().sendNotificationToDriverMAP( Get.find<FirebaseMessagesController>().sendNotificationToDriverMAP(
'Wallet Added'.tr, 'Wallet Added'.tr,
'Wallet Added${(remainingFee).toStringAsFixed(0)}'.tr, 'Wallet Added${(remainingFee).toStringAsFixed(0)}'.tr,
Get.find<MapDriverController>().tokenPassenger, Get.find<MapDriverController>().tokenPassenger,

View File

@@ -1,9 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'dart:math';
import 'package:sefer_driver/constant/box_name.dart';
import 'package:sefer_driver/controller/payment/paymob/paymob_response.dart';
import 'package:sefer_driver/views/home/Captin/orderCaptin/order_request_page.dart'; import 'package:sefer_driver/views/home/Captin/orderCaptin/order_request_page.dart';
import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:firebase_messaging/firebase_messaging.dart';
@@ -15,103 +12,102 @@ import 'package:flutter_stripe/flutter_stripe.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart'; import 'package:get_storage/get_storage.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:wakelock_plus/wakelock_plus.dart'; import 'package:wakelock_plus/wakelock_plus.dart';
import 'constant/api_key.dart'; import 'constant/api_key.dart';
import 'constant/info.dart'; import 'constant/info.dart';
import 'constant/notification.dart';
import 'controller/firebase/firbase_messge.dart'; import 'controller/firebase/firbase_messge.dart';
import 'controller/firebase/local_notification.dart'; import 'controller/firebase/local_notification.dart';
import 'controller/functions/encrypt_decrypt.dart'; import 'controller/functions/encrypt_decrypt.dart';
import 'controller/functions/location_controller.dart';
import 'controller/functions/secure_storage.dart'; import 'controller/functions/secure_storage.dart';
import 'controller/local/local_controller.dart'; import 'controller/local/local_controller.dart';
import 'controller/local/translations.dart'; import 'controller/local/translations.dart';
import 'controller/payment/paymob/paymob_wallet.dart';
import 'firebase_options.dart'; import 'firebase_options.dart';
import 'models/db_sql.dart'; import 'models/db_sql.dart';
import 'print.dart'; import 'print.dart';
import 'splash_screen_page.dart'; import 'splash_screen_page.dart';
import 'views/home/Captin/driver_map_page.dart';
import 'views/home/Captin/orderCaptin/order_over_lay.dart'; import 'views/home/Captin/orderCaptin/order_over_lay.dart';
//--- Global Variables ---
final box = GetStorage(); final box = GetStorage();
const storage = FlutterSecureStorage(); const storage = FlutterSecureStorage();
final PaymobPayment paymobPayment = PaymobPayment();
final PaymobPaymentWallet paymobPaymentWallet = PaymobPaymentWallet();
DbSql sql = DbSql.instance; DbSql sql = DbSql.instance;
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>(); final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
const platform = MethodChannel('com.sefer_driver/app_control');
//--- Entry Points for Background/Terminated States ---
@pragma('vm:entry-point') @pragma('vm:entry-point')
Future<void> backgroundMessageHandler(RemoteMessage message) async { Future<void> backgroundMessageHandler(RemoteMessage message) async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(); await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
await GetStorage.init();
if (!await FlutterOverlayWindow.isPermissionGranted()) { if (!await FlutterOverlayWindow.isPermissionGranted()) {
// بإمكانك تجاهل الطلب في الخلفية والاكتفاء بالتنبيه
Log.print("Overlay permission not granted; showing only notification."); Log.print("Overlay permission not granted; showing only notification.");
} }
if (Platform.isAndroid) { if (Platform.isAndroid) {
if (message.notification != null && message.notification!.title != null) { if (message.notification != null && message.notification!.title != null) {
Log.print('message.notification!.title: ${message.notification!.title}'); Log.print('message.notification!.title: ${message.notification!.title}');
if (message.notification?.title == 'طلب' || if (message.notification?.title == 'Order' ||
message.notification?.title == 'OrderSpeed') { message.notification?.title == 'OrderSpeed') {
var myListString = message.data['DriverList'] ?? '[]'; var myListString = message.data['DriverList'] ?? '[]';
Log.print('myListString: $myListString'); Log.print('myListString: $myListString');
// Decode the JSON string to a list
List<dynamic> myList; List<dynamic> myList;
try { try {
myList = jsonDecode(myListString) as List<dynamic>; myList = jsonDecode(myListString) as List<dynamic>;
Log.print('myList: ${myList}');
} catch (e) { } catch (e) {
Log.print('Error decoding JSON: $e'); Log.print('Error decoding JSON: $e');
myList = []; myList = [];
} }
await Future.delayed(const Duration(seconds: 1));
bool isOverlayActive = await FlutterOverlayWindow.isActive(); bool isOverlayActive = await FlutterOverlayWindow.isActive();
if (isOverlayActive) { if (isOverlayActive) {
await FlutterOverlayWindow.closeOverlay();
}
await FlutterOverlayWindow.shareData(myList); await FlutterOverlayWindow.shareData(myList);
} else {
await FlutterOverlayWindow.showOverlay( await FlutterOverlayWindow.showOverlay(
enableDrag: true, enableDrag: true,
flag: OverlayFlag.focusPointer, flag: OverlayFlag.focusPointer,
// visibility: NotificationVisibility.visibilityPublic,
positionGravity: PositionGravity.auto, positionGravity: PositionGravity.auto,
height: 1300, height: 1400,
width: WindowSize.matchParent, width: WindowSize.matchParent,
startPosition: const OverlayPosition(0, -40), startPosition: const OverlayPosition(0, -30),
); );
await FlutterOverlayWindow.shareData(myList);
}
// It's better to manage notifications in one place if possible
// but this is fine if it works for you.
NotificationController().showNotification( NotificationController().showNotification(
message.notification!.title.toString(), message.notification!.title.toString(),
message.notification!.body.toString(), message.notification!.body.toString(),
'order', 'order',
myListString, myListString,
); );
await FlutterOverlayWindow.shareData(myList);
}
} else { } else {
// Handle other types of notifications
FirebaseMessagesController().fireBaseTitles(message); FirebaseMessagesController().fireBaseTitles(message);
} }
} }
} }
}
@pragma('vm:entry-point') @pragma('vm:entry-point')
void notificationTapBackground(NotificationResponse notificationResponse) { void notificationTapBackground(NotificationResponse notificationResponse) {
// handle background notification taps here Log.print('Notification tapped in background!');
print('Notification tapped in background!');
NotificationController().handleNotificationResponse(notificationResponse); NotificationController().handleNotificationResponse(notificationResponse);
// You can add your logic here to handle the notification tap
} }
@pragma('vm:entry-point') @pragma('vm:entry-point')
void overlayMain() async { void overlayMain() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
await GetStorage.init();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(const MaterialApp( runApp(const MaterialApp(
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
home: OrderOverlay(), home: OrderOverlay(),
@@ -119,12 +115,12 @@ void overlayMain() async {
} }
Future<void> closeOverLay() async { Future<void> closeOverLay() async {
// FlutterOverlayWindow.closeOverlay();
bool isOverlayActive = await FlutterOverlayWindow.isActive(); bool isOverlayActive = await FlutterOverlayWindow.isActive();
if (isOverlayActive) { if (isOverlayActive) {
await FlutterOverlayWindow.closeOverlay(); await FlutterOverlayWindow.closeOverlay();
} }
} }
//--- Main Application ---
void main() async { void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
@@ -136,21 +132,29 @@ void main() async {
DeviceOrientation.portraitDown, DeviceOrientation.portraitDown,
]); ]);
runApp(MyApp()); runApp(const MyApp());
} }
class MyApp extends StatefulWidget { class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override @override
_MyAppState createState() => _MyAppState(); _MyAppState createState() => _MyAppState();
} }
class _MyAppState extends State<MyApp> { class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
WidgetsBinding.instance.addObserver(this);
_initApp(); _initApp();
} }
@override
void dispose() {
super.dispose();
}
Future<void> _initApp() async { Future<void> _initApp() async {
try { try {
await Firebase.initializeApp( await Firebase.initializeApp(
@@ -159,62 +163,23 @@ class _MyAppState extends State<MyApp> {
await initializer.initializeApp(); await initializer.initializeApp();
await EncryptionHelper.initialize(); await EncryptionHelper.initialize();
if (Platform.isAndroid || Platform.isIOS) { Get.put(NotificationController());
Get.put( Get.put(FirebaseMessagesController());
NotificationController()); // Initialize NotificationController here
await FirebaseMessaging.instance.requestPermission(); await FirebaseMessaging.instance.requestPermission();
FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler); FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler);
await NotificationController().initNotifications(); await NotificationController().initNotifications();
// Generate a random index to pick a message // You can add your other initializations here
final random = Random(); // For example:
final randomMessage =
driverMessages[random.nextInt(driverMessages.length)];
// Schedule the notification with the random message
NotificationController().scheduleNotificationsForSevenDays(
randomMessage.split(':')[0],
randomMessage.split(':')[1],
"ding",
);
await Future.wait([ // Your other startup logic...
FirebaseMessagesController().getNotificationSettings(),
FirebaseMessagesController().getToken(),
]);
// PermissionStatus status1 = await Permission.location.status;
// if (status1.isGranted) {
// await LocationController().startLocationUpdates();
// }
}
String? key = (await storage.read(key: BoxName.payMobApikey));
if (key != null) {
String? apiKey = (key);
if (apiKey != null) {
PaymobPayment.instance.initialize(
// Use .instance
apiKey: apiKey,
integrationID: int.parse(AK.integrationIdPayMob),
userTokenExpiration: 200,
iFrameID: 837992,
);
PaymobPaymentWallet.instance.initialize(
// Use .instance
apiKey: apiKey,
integrationID: int.parse(AK.integrationIdPayMobWallet),
userTokenExpiration: 200,
iFrameID: 837992,
);
}
}
} catch (e) { } catch (e) {
print("Error initializing app: $e"); Log.print("Error during _initApp: $e");
// Handle initialization errors appropriately. Maybe show an error message to the user.
} }
} }
//--- Build Method ---
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
LocaleController localController = Get.put(LocaleController()); LocaleController localController = Get.put(LocaleController());
@@ -231,105 +196,11 @@ class _MyAppState extends State<MyApp> {
GetPage( GetPage(
name: '/order-page', name: '/order-page',
page: () => OrderRequestPage(), page: () => OrderRequestPage(),
arguments: box.read(BoxName.rideArguments),
), ),
GetPage(
name: '/passenger-location-map',
page: () => PassengerLocationMapPage()),
], ],
); );
} }
} }
// void main() async {
// WidgetsFlutterBinding.ensureInitialized();
// await WakelockPlus.enable();
//
// await GetStorage.init();
//
// final AppInitializer initializer = AppInitializer();
//
// await initializer.initializeApp();
// await Future.delayed(Duration.zero);
// await EncryptionHelper.initialize();
//
// Stripe.publishableKey = AK.publishableKeyStripe;
//
// PermissionStatus status1 = await Permission.location.status;
// // if (status1.isGranted) {
// await LocationController().startLocationUpdates();
// // }
//
// if (Platform.isAndroid || Platform.isIOS) {
// NotificationController notificationController =
// Get.put(NotificationController());
// await Firebase.initializeApp(
// options: DefaultFirebaseOptions.currentPlatform,
// );
// await FirebaseMessagesController().requestFirebaseMessagingPermission();
//
// FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler);
//
// await notificationController.initNotifications();
//
// // Generate a random index to pick a message
// final random = Random();
// final randomMessage = driverMessages[random.nextInt(driverMessages.length)];
//
// // Schedule the notification with the random message
// notificationController.scheduleNotificationsForSevenDays(
// randomMessage.split(':')[0],
// randomMessage.split(':')[1],
// "ding",
// );
//
// await Future.wait([
// FirebaseMessagesController().getNotificationSettings(),
// FirebaseMessagesController().getToken(),
// ]);
// // await FacebookAuth.instance.init();
// SystemChrome.setPreferredOrientations([
// DeviceOrientation.portraitUp,
// DeviceOrientation.portraitDown,
// ]);
// }
//
// String? key = (await storage.read(key: BoxName.payMobApikey));
//
// String? apiKey = EncryptionHelper.instance.decryptData(key!);
// PaymobPayment.instance.initialize(
// apiKey: apiKey,
// integrationID: int.parse(AK.integrationIdPayMob),
// userTokenExpiration: 200,
// iFrameID: 837992,
// );
//
// PaymobPaymentWallet.instance.initialize(
// apiKey: apiKey,
// integrationID: int.parse(AK.integrationIdPayMobWallet),
// userTokenExpiration: 200,
// iFrameID: 837992,
// );
// runApp(MyApp());
// }
//
// class MyApp extends StatelessWidget {
// @override
// Widget build(BuildContext context) {
// LocaleController localController = Get.put(LocaleController());
// return GetMaterialApp(
// navigatorKey: navigatorKey,
// title: AppInformation.appName,
// translations: MyTranslation(),
// debugShowCheckedModeBanner: false,
// locale: localController.language,
// theme: localController.appTheme,
// initialRoute: '/',
// getPages: [
// GetPage(name: '/', page: () => SplashScreen()),
// GetPage(
// name: '/order-page',
// page: () => OrderRequestPage(),
// arguments: box.read(BoxName.rideArguments),
// ),
// ],
// );
// }
// }

View File

@@ -1,16 +1,18 @@
// lib/models/order_data.dart // lib/models/model/order_data.dart
class OrderData { class OrderData {
final String customerName; final String customerName;
final double tripDistanceKm; // المسافة الكلية للرحلة بالكيلومتر final String customerToken;
final double tripDistanceKm; // The total trip distance in kilometers
final String price; final String price;
final String startLocationAddress; final String startLocationAddress;
final String endLocationAddress; final String endLocationAddress;
final double distanceToPassengerKm; // المسافة إلى الراكب بالكيلومتر final double
final int tripDurationMinutes; // مدة الرحلة الكلية بالدقائق (مقربة لأعلى) distanceToPassengerKm; // The distance to the passenger in kilometers
final int tripDurationMinutes; // Total trip duration in minutes (rounded up)
final int final int
durationToPassengerMinutes; // المدة إلى الراكب بالدقائق (مقربة لأعلى) durationToPassengerMinutes; // Duration to reach the passenger in minutes (rounded up)
final String rideType; final String rideType;
final String orderId; final String orderId;
@@ -22,6 +24,7 @@ class OrderData {
OrderData({ OrderData({
required this.customerName, required this.customerName,
required this.customerToken,
required this.tripDistanceKm, required this.tripDistanceKm,
required this.price, required this.price,
required this.startLocationAddress, required this.startLocationAddress,
@@ -37,26 +40,57 @@ class OrderData {
this.rawEndCoordinates, this.rawEndCoordinates,
}); });
// دالة مساعدة لتحويل الثواني إلى دقائق وتقريبها لأعلى // --- NEW: Factory constructor to create an instance from a Map ---
// This is the missing method that was causing the error.
factory OrderData.fromMap(Map<String, dynamic> map) {
return OrderData(
// For strings, provide a default value in case the map key is null
customerName: map['customerName']?.toString() ?? 'Unknown Customer',
customerToken: map['customerToken']?.toString() ?? 'Unknown token',
// For numbers, cast from 'num' to handle both int and double, with a default value
tripDistanceKm: (map['tripDistanceKm'] as num?)?.toDouble() ?? 0.0,
price: map['price']?.toString() ?? '0',
startLocationAddress:
map['startLocationAddress']?.toString() ?? 'Unknown Address',
endLocationAddress:
map['endLocationAddress']?.toString() ?? 'Unknown Address',
distanceToPassengerKm:
(map['distanceToPassengerKm'] as num?)?.toDouble() ?? 0.0,
tripDurationMinutes: (map['tripDurationMinutes'] as num?)?.toInt() ?? 0,
durationToPassengerMinutes:
(map['durationToPassengerMinutes'] as num?)?.toInt() ?? 0,
rideType: map['rideType']?.toString() ?? 'Unknown',
orderId: map['orderId']?.toString() ?? 'N/A',
passengerId: map['passengerId']?.toString() ?? 'N/A',
passengerRate: map['passengerRate']?.toString() ?? 'N/A',
// For nullable strings, direct access is fine as it returns null if the key doesn't exist
rawStartCoordinates: map['rawStartCoordinates'],
rawEndCoordinates: map['rawEndCoordinates'],
);
}
// A helper function to convert seconds to rounded-up minutes
static int _secondsToRoundedUpMinutes(String secondsString) { static int _secondsToRoundedUpMinutes(String secondsString) {
final seconds = double.tryParse(secondsString) ?? 0.0; final seconds = double.tryParse(secondsString) ?? 0.0;
if (seconds <= 0) return 0; if (seconds <= 0) return 0;
return (seconds / 60) return (seconds / 60)
.ceil(); // .ceil() لتقريب الكسر لأعلى (مثلاً 0.1 دقيقة تصبح 1 دقيقة) .ceil(); // .ceil() rounds up (e.g., 0.1 minutes becomes 1 minute)
} }
// Your existing factory for creating an instance from a List
factory OrderData.fromList(List<dynamic> list) { factory OrderData.fromList(List<dynamic> list) {
// بناءً على testList والافتراضات الجديدة:
// list[4]: durationToRide (مدة الرحلة الكلية بالثواني)
// list[5]: distance (المسافة الكلية للرحلة بالكيلومتر)
// list[12]: distanceByPassenger (المسافة إلى الراكب بالمتر)
// list[15]: durationToPassenger (المدة إلى الراكب بالثواني)
double distanceToPassengerMeters = double distanceToPassengerMeters =
list.length > 12 ? (double.tryParse(list[12].toString()) ?? 0.0) : 0.0; list.length > 12 ? (double.tryParse(list[12].toString()) ?? 0.0) : 0.0;
return OrderData( return OrderData(
customerName: list.length > 8 ? list[8].toString() : 'Unknown Customer', customerName: list.length > 8 ? list[8].toString() : 'Unknown Customer',
customerToken: list.length > 9 ? list[9].toString() : 'Unknown token',
tripDistanceKm: tripDistanceKm:
list.length > 5 ? (double.tryParse(list[5].toString()) ?? 0.0) : 0.0, list.length > 5 ? (double.tryParse(list[5].toString()) ?? 0.0) : 0.0,
price: list.length > 2 ? list[2].toString().split('.')[0] : '0', price: list.length > 2 ? list[2].toString().split('.')[0] : '0',
@@ -66,7 +100,7 @@ class OrderData {
list.length > 30 ? list[30].toString() : 'Unknown Address', list.length > 30 ? list[30].toString() : 'Unknown Address',
distanceToPassengerKm: distanceToPassengerKm:
distanceToPassengerMeters / 1000.0, // تحويل من متر إلى كيلومتر distanceToPassengerMeters / 1000.0, // Convert meters to kilometers
tripDurationMinutes: tripDurationMinutes:
list.length > 4 ? _secondsToRoundedUpMinutes(list[4].toString()) : 0, list.length > 4 ? _secondsToRoundedUpMinutes(list[4].toString()) : 0,
@@ -102,6 +136,7 @@ class OrderData {
} }
} }
// Getter to parse start coordinates
Map<String, double?>? get startCoordinates { Map<String, double?>? get startCoordinates {
if (rawStartCoordinates == null) return null; if (rawStartCoordinates == null) return null;
final parts = rawStartCoordinates!.split(','); final parts = rawStartCoordinates!.split(',');
@@ -114,6 +149,7 @@ class OrderData {
return null; return null;
} }
// Getter to parse end coordinates
Map<String, double?>? get endCoordinates { Map<String, double?>? get endCoordinates {
if (rawEndCoordinates == null) return null; if (rawEndCoordinates == null) return null;
final parts = rawEndCoordinates!.split(','); final parts = rawEndCoordinates!.split(',');
@@ -126,6 +162,8 @@ class OrderData {
return null; return null;
} }
// Your existing method to convert the object TO a Map.
// This is used to pass the data from the overlay to the main app.
Map<String, dynamic> toMap() { Map<String, dynamic> toMap() {
return { return {
'customerName': customerName, 'customerName': customerName,

View File

@@ -0,0 +1,13 @@
import 'package:flutter/services.dart';
class OverlayMethodChannel {
static const _channel = MethodChannel('com.sefer_driver/app_control');
static Future<void> bringToForeground() async {
try {
await _channel.invokeMethod('bringToForeground');
} on PlatformException catch (e) {
print('Error bringing app to foreground: $e');
}
}
}

View File

@@ -104,13 +104,14 @@ class CountryPickerFromSetting extends StatelessWidget {
final List<String> countryOptions = [ final List<String> countryOptions = [
'Jordan', 'Jordan',
'USA', "Syria",
'Egypt', 'Egypt',
'Turkey', 'Turkey',
'Saudi Arabia', 'Saudi Arabia',
'Qatar', 'Qatar',
'Bahrain', 'Bahrain',
'Kuwait', 'Kuwait',
'USA',
]; ];
CountryPickerFromSetting({Key? key}) : super(key: key); CountryPickerFromSetting({Key? key}) : super(key: key);

View File

@@ -28,7 +28,7 @@ class FrequentlyQuestionsPage extends StatelessWidget {
), ),
children: [ children: [
Text( Text(
'Step-by-step instructions on how to request a ride through the Sefer app.' 'Step-by-step instructions on how to request a ride through the Tripz app.'
.tr, .tr,
style: AppStyle.title, style: AppStyle.title,
), ),
@@ -43,7 +43,7 @@ class FrequentlyQuestionsPage extends StatelessWidget {
), ),
children: [ children: [
Text( Text(
'Sefer offers a variety of vehicle options to suit your needs, including economy, comfort, and luxury. Choose the option that best fits your budget and passenger count.' 'Tripz offers a variety of vehicle options to suit your needs, including economy, comfort, and luxury. Choose the option that best fits your budget and passenger count.'
.tr, .tr,
style: AppStyle.title, style: AppStyle.title,
), ),
@@ -58,7 +58,7 @@ class FrequentlyQuestionsPage extends StatelessWidget {
), ),
children: [ children: [
Text( Text(
'Sefer offers multiple payment methods for your convenience. Choose between cash payment or credit/debit card payment during ride confirmation.' 'Tripz offers multiple payment methods for your convenience. Choose between cash payment or credit/debit card payment during ride confirmation.'
.tr, .tr,
style: AppStyle.title, style: AppStyle.title,
), ),
@@ -73,7 +73,7 @@ class FrequentlyQuestionsPage extends StatelessWidget {
), ),
children: [ children: [
Text( Text(
'Yes, you can cancel your ride under certain conditions (e.g., before driver is assigned). See the Sefer cancellation policy for details.' 'Yes, you can cancel your ride under certain conditions (e.g., before driver is assigned). See the Tripz cancellation policy for details.'
.tr, .tr,
style: AppStyle.title, style: AppStyle.title,
), ),
@@ -98,7 +98,7 @@ class FrequentlyQuestionsPage extends StatelessWidget {
}); });
}, },
child: Text( child: Text(
'Visit our website or contact Sefer support for information on driver registration and requirements.' 'Visit our website or contact Tripz support for information on driver registration and requirements.'
.tr, .tr,
style: AppStyle.title, style: AppStyle.title,
), ),
@@ -115,22 +115,22 @@ class FrequentlyQuestionsPage extends StatelessWidget {
), ),
children: [ children: [
Text( Text(
'Sefer provides in-app chat functionality to allow you to communicate with your driver or passenger during your ride.' 'Tripz provides in-app chat functionality to allow you to communicate with your driver or passenger during your ride.'
.tr, .tr,
style: AppStyle.title, style: AppStyle.title,
), ),
], ],
), ),
// Question 8: What safety measures does Sefer offer? // Question 8: What safety measures does Tripz offer?
ExpansionTile( ExpansionTile(
title: Text( title: Text(
'What safety measures does Sefer offer?'.tr, 'What safety measures does Tripz offer?'.tr,
style: AppStyle.title, style: AppStyle.title,
), ),
children: [ children: [
Text( Text(
'Sefer prioritizes your safety. We offer features like driver verification, in-app trip tracking, and emergency contact options.' 'Tripz prioritizes your safety. We offer features like driver verification, in-app trip tracking, and emergency contact options.'
.tr, .tr,
style: AppStyle.title, style: AppStyle.title,
), ),

View File

@@ -120,7 +120,7 @@ class SettingsCaptain extends StatelessWidget {
CupertinoListTile( CupertinoListTile(
leading: const Icon(CupertinoIcons.hand_raised_fill), leading: const Icon(CupertinoIcons.hand_raised_fill),
title: title:
Text("How to use SEFER".tr, style: AppStyle.headTitle2), Text("How to use Tripz".tr, style: AppStyle.headTitle2),
trailing: const CupertinoListTileChevron(), trailing: const CupertinoListTileChevron(),
onTap: () => Get.to(() => const UsingAppPage()), onTap: () => Get.to(() => const UsingAppPage()),
), ),

View File

@@ -10,7 +10,7 @@ class UsingAppPage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MyScafolld( return MyScafolld(
title: "How to use SEFER".tr, title: "How to use Tripz".tr,
body: [ body: [
SizedBox( SizedBox(
child: Padding( child: Padding(
@@ -22,12 +22,13 @@ class UsingAppPage extends StatelessWidget {
MyDialogContent().getDialog( MyDialogContent().getDialog(
"What are the order details we provide to you?".tr, "What are the order details we provide to you?".tr,
Image.network( Image.network(
'https://api.sefer.live/sefer/imageForUsingApp/order_page.jpg', 'https://api.tripz-egypt.com/tripz/imageForUsingApp/order_page.jpg',
height: 300, height: 300,
width: 300, width: 300,
fit: BoxFit.cover, fit: BoxFit.cover,
), ), () {
() {}); Get.back();
});
}, },
child: Container( child: Container(
decoration: AppStyle.boxDecoration1, decoration: AppStyle.boxDecoration1,
@@ -47,16 +48,17 @@ class UsingAppPage extends StatelessWidget {
onTap: () { onTap: () {
MyDialog().getDialog( MyDialog().getDialog(
"What are the order details we provide to you?".tr, "What are the order details we provide to you?".tr,
'''Sefer Wallet Features: '''Tripz Wallet Features:
Transfer money multiple times. Transfer money multiple times.
Transfer to anyone. Transfer to anyone.
Make purchases. Make purchases.
Charge your account. Charge your account.
Charge a friend's Sefer account. Charge a friend's Tripz account.
Store your money with us and receive it in your bank as a monthly salary.''' Store your money with us and receive it in your bank as a monthly salary.'''
.tr, .tr, () {
() {}); Get.back();
});
}, },
child: Container( child: Container(
decoration: AppStyle.boxDecoration1, decoration: AppStyle.boxDecoration1,
@@ -75,8 +77,8 @@ Store your money with us and receive it in your bank as a monthly salary.'''
InkWell( InkWell(
onTap: () { onTap: () {
MyDialog().getDialog( MyDialog().getDialog(
"What are the order details we provide to you?".tr, "What is Types of Trips in Tripz?".tr,
'''Types of Trips in Sefer: '''Types of Trips in Tripz:
Comfort: For cars newer than 2017 with air conditioning. Comfort: For cars newer than 2017 with air conditioning.
Lady: For girl drivers. Lady: For girl drivers.
@@ -84,15 +86,16 @@ Speed: For fixed salary and endpoints.
Mashwari: For flexible trips where passengers choose the car and driver with prior arrangements. Mashwari: For flexible trips where passengers choose the car and driver with prior arrangements.
Raih Gai: For same-day return trips longer than 50km. Raih Gai: For same-day return trips longer than 50km.
''' '''
.tr, .tr, () {
() {}); Get.back();
});
}, },
child: Container( child: Container(
decoration: AppStyle.boxDecoration1, decoration: AppStyle.boxDecoration1,
child: Padding( child: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Text( child: Text(
"What is Types of Trips in Sefer?".tr, "What is Types of Trips in Tripz?".tr,
style: AppStyle.title, style: AppStyle.title,
), ),
), ),

View File

@@ -21,16 +21,20 @@ class PassengerLocationMapPage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// if (!mapDriverController.initialized) { if (Get.arguments != null && Get.arguments is Map<String, dynamic>) {
// // Call a method to initialize the controller // نستخدم addPostFrameCallback لضمان أن هذا الكود يعمل بعد اكتمال بناء الإطار الأول
// هذا يعطي GetX وقته لتجهيز كل شيء
// mapDriverController.initialized; WidgetsBinding.instance.addPostFrameCallback((_) {
// } else { // نستدعي دالة التهيئة الجديدة ونمرر لها البيانات
// Get.put(MapDriverController()).argumentLoading(); mapDriverController.argumentLoading();
});
// Get.put(MapDriverController()) } else {
// .startTimerToShowPassengerInfoWindowFromDriver(); // في حال عدم وجود arguments، يجب التعامل مع هذا الخطأ
// } WidgetsBinding.instance.addPostFrameCallback((_) {
Get.snackbar("Error", "No order data found.");
Get.back();
});
}
mapDriverController.argumentLoading(); mapDriverController.argumentLoading();
mapDriverController.startTimerToShowPassengerInfoWindowFromDriver(); mapDriverController.startTimerToShowPassengerInfoWindowFromDriver();

View File

@@ -19,6 +19,7 @@ import '../../../../controller/functions/location_controller.dart';
import '../../../../controller/functions/overlay_permisssion.dart'; import '../../../../controller/functions/overlay_permisssion.dart';
import '../../../../controller/functions/package_info.dart'; import '../../../../controller/functions/package_info.dart';
import '../../../../controller/home/captin/home_captain_controller.dart'; import '../../../../controller/home/captin/home_captain_controller.dart';
import '../../../../print.dart';
import '../../../widgets/circle_container.dart'; import '../../../widgets/circle_container.dart';
import '../driver_map_page.dart'; import '../driver_map_page.dart';
import 'widget/connect.dart'; import 'widget/connect.dart';
@@ -482,6 +483,8 @@ class HomeCaptain extends StatelessWidget {
), ),
GetBuilder<HomeCaptainController>( GetBuilder<HomeCaptainController>(
builder: (homeCaptainController) { builder: (homeCaptainController) {
Log.print(
'rideStatus from home 486 : ${box.read(BoxName.rideStatus)}');
return box.read(BoxName.rideStatus) == 'Applied' || return box.read(BoxName.rideStatus) == 'Applied' ||
box.read(BoxName.rideStatus) == 'Begin' box.read(BoxName.rideStatus) == 'Begin'
? Positioned( ? Positioned(
@@ -520,7 +523,7 @@ class HomeCaptain extends StatelessWidget {
}; };
}, },
icon: const Icon( icon: const Icon(
Icons.rice_bowl, Icons.directions_rounded,
size: 29, size: 29,
color: AppColor.blueColor, color: AppColor.blueColor,
), ),

View File

@@ -1,13 +1,21 @@
import 'package:sefer_driver/constant/box_name.dart'; import 'package:sefer_driver/constant/box_name.dart';
import 'package:sefer_driver/controller/firebase/local_notification.dart'; import 'package:sefer_driver/controller/firebase/local_notification.dart';
import 'package:sefer_driver/main.dart'; import 'package:sefer_driver/main.dart';
import 'package:sefer_driver/print.dart';
import 'package:sefer_driver/views/home/Captin/driver_map_page.dart';
import 'package:sefer_driver/views/home/Captin/orderCaptin/vip_order_page.dart'; import 'package:sefer_driver/views/home/Captin/orderCaptin/vip_order_page.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_font_icons/flutter_font_icons.dart'; import 'package:flutter_font_icons/flutter_font_icons.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:sefer_driver/controller/home/captin/home_captain_controller.dart'; import 'package:sefer_driver/controller/home/captin/home_captain_controller.dart';
import 'package:sefer_driver/views/widgets/error_snakbar.dart';
import 'package:sefer_driver/views/widgets/mydialoug.dart';
import '../../../../../constant/colors.dart'; import '../../../../../constant/colors.dart';
import '../../../../../constant/links.dart';
import '../../../../../controller/firebase/firbase_messge.dart';
import '../../../../../controller/functions/crud.dart';
import '../../../../../controller/home/captin/order_request_controller.dart';
import '../../../../Rate/ride_calculate_driver.dart'; import '../../../../Rate/ride_calculate_driver.dart';
GetBuilder<HomeCaptainController> leftMainMenuCaptainIcons() { GetBuilder<HomeCaptainController> leftMainMenuCaptainIcons() {
@@ -17,6 +25,46 @@ GetBuilder<HomeCaptainController> leftMainMenuCaptainIcons() {
left: 6, left: 6,
child: Column( child: Column(
children: [ children: [
AnimatedContainer(
duration: const Duration(microseconds: 200),
width: controller.widthMapTypeAndTraffic,
decoration: BoxDecoration(
color: AppColor.secondaryColor,
border: Border.all(color: AppColor.blueColor),
borderRadius: BorderRadius.circular(15)),
child: Builder(builder: (context) {
return IconButton(
onPressed: () async {
await checkForPendingOrderFromServer();
box.read(BoxName.rideArgumentsFromBackground) != 'failure'
? Get.to(() => PassengerLocationMapPage(),
arguments:
box.read(BoxName.rideArgumentsFromBackground))
: MyDialog().getDialog(
'Ride info'.tr,
'you dont have accepted ride'.tr,
() {
Get.back();
},
);
// Log.print(
// 'box.read(BoxName.rideArgumentsFromBackground): ${box.read(BoxName.rideArgumentsFromBackground)}');
},
icon: Icon(
Icons.directions_car_rounded,
size: 29,
color:
box.read(BoxName.rideArgumentsFromBackground) == 'failure'
? AppColor.redColor
: AppColor.greenColor,
),
);
}),
),
const SizedBox(
height: 5,
),
AnimatedContainer( AnimatedContainer(
duration: const Duration(microseconds: 200), duration: const Duration(microseconds: 200),
width: controller.widthMapTypeAndTraffic, width: controller.widthMapTypeAndTraffic,
@@ -89,7 +137,10 @@ GetBuilder<HomeCaptainController> leftMainMenuCaptainIcons() {
}), }),
) )
: const SizedBox(), : const SizedBox(),
// : const SizedBox(), // const SizedBox(
// height: 5,
// ),
// AnimatedContainer( // AnimatedContainer(
// duration: const Duration(microseconds: 200), // duration: const Duration(microseconds: 200),
// width: controller.widthMapTypeAndTraffic, // width: controller.widthMapTypeAndTraffic,
@@ -100,53 +151,7 @@ GetBuilder<HomeCaptainController> leftMainMenuCaptainIcons() {
// child: Builder(builder: (context) { // child: Builder(builder: (context) {
// return IconButton( // return IconButton(
// onPressed: () async { // onPressed: () async {
// final List<dynamic> testList = const [ // Log.print('phoneDriver: ${box.read(BoxName.phoneDriver)}');
// "32.1117875,36.0669891",
// "32.1364001,36.0707479",
// "24.84",
// "7.56",
// "436",
// "4.38",
// "109270481246447459618",
// "113172279072358305645",
// "hamza",
// "e4QWqe7K607luM7qUMOPCL:APA91bFjX4XBM4I5COJl9fyxCTKJ1ZQpT3vzY7iEbOTuT4uo0-OSCAt5zgVhlhw4aC33s-VhyucDnP1tQGFd9svaazQ8A_SKgolPk3owzug8dCsiXoPeJ0k",
// "+201010101010",
// "6",
// "43",
// "true",
// "c2tXiuBJQCSg4CU4IfqYOL:APA91bFA0f8R3QMnPQnPEEdNyjY-jcoKt4nLBHxcLLsmDSuJn5yd4jSvwq7qDIZpkkPkjfjdwdKsGL0-G0aHpPyjfiBvbCwFmlRMCUKftNMNT7MJx2Bp16Y",
// "6",
// "1188",
// "false",
// "109270481246447459618",
// "436",
// "startEnd",
// "32.12404505187645,36.06566168367863",
// "",
// "",
// "",
// "",
// "5.42",
// "0",
// "hamzaayedflutter@gmail.com",
// "4368+PPP، السخنة، الأردن",
// "43PC+C4G، السخنة، الأردن",
// "Speed",
// "8",
// "5.00"
// ];
// await FlutterOverlayWindow.shareData(testList);
// await FlutterOverlayWindow.showOverlay(
// enableDrag: true,
// flag: OverlayFlag.focusPointer,
// // visibility: NotificationVisibility.visibilityPublic,
// positionGravity: PositionGravity.auto,
// height: 1300,
// width: WindowSize.matchParent,
// startPosition: const OverlayPosition(0, -90),
// );
// debugPrint('Overlay opened: ');
// }, // },
// icon: const Icon( // icon: const Icon(
// FontAwesome5.grin_tears, // FontAwesome5.grin_tears,
@@ -165,3 +170,142 @@ GetBuilder<HomeCaptainController> leftMainMenuCaptainIcons() {
), ),
); );
} }
void _log(String message) => print(message);
Future<void> checkForPendingOrderFromServer() async {
bool _isProcessingOrder = false;
if (_isProcessingOrder) return;
final driverId = box.read(BoxName.driverID)?.toString();
if (driverId == null) return; // Can't check without a driver ID
_isProcessingOrder = true; // Lock
try {
// You need to create this CRUD method
var response = await CRUD().post(
link: AppLink.getArgumentAfterAppliedFromBackground,
payload: {'driver_id': driverId},
);
// Assuming the server returns order data if found, or 'failure'/'none' if not
if (response != 'failure') {
Log.print('response: ${response}');
_log("MAIN_APP_LOG: Pending order DETECTED from server!");
final Map<String, dynamic> orderInfoFromServer = response['message'];
final Map<String, dynamic> rideArguments =
_transformServerDataToAppArguments(orderInfoFromServer);
// 2. Build the new arguments map, matching your Flutter structure
_log("MAIN_APP_LOG: Constructed rideArguments map successfully.");
/////////////
final customerToken = (response)['message']['token_passenger'];
final orderId = (response)['message']['ride_id'].toString();
Log.print('orderId: ${orderId}');
box.write(BoxName.rideArgumentsFromBackground, rideArguments);
box.write(BoxName.statusDriverLocation, 'on');
box.write(BoxName.rideStatus, 'Apply');
Get.put(OrderRequestController()).changeApplied();
// MyDialog().getDialog(orderId.toString(), customerToken, () {});
// Now proceed with the UI flow
_sendAcceptanceNotification(customerToken, orderId.toString());
// await _bringAppToForegroundAndNavigate(orderId);
} else {
_log("MAIN_APP_LOG: No pending orders found on server.");
box.write(BoxName.rideArgumentsFromBackground, 'failure');
}
} catch (e) {
_log("Error while polling server: $e");
} finally {
_isProcessingOrder = false; // Release lock
}
}
Map<String, dynamic> _transformServerDataToAppArguments(
Map<String, dynamic> serverData) {
_log("Transforming server data to match app's argument structure.");
// Helper function to safely get and convert values to String
String _getString(String key, [String defaultValue = 'unknown']) {
// serverData[key] might be an int, double, or string. .toString() handles all.
// If it's null, use the default value.
return serverData[key]?.toString() ?? defaultValue;
}
return {
'passengerLocation': _getString('passenger_location'),
'passengerDestination': _getString('passenger_destination'),
'Duration': _getString('duration'),
'totalCost': _getString('total_cost'),
'Distance': _getString('distance'),
'name': _getString('name'),
'phone': _getString('phone'),
'email': _getString('email'),
'tokenPassenger': _getString('token_passenger'),
'direction': _getString('direction_url'),
'DurationToPassenger': _getString('duration_to_passenger'),
'rideId': _getString('ride_id'),
'passengerId': _getString('passenger_id'),
'driverId': _getString('driver_id'),
'durationOfRideValue': _getString('duration_of_ride'),
'paymentAmount': _getString('payment_amount'),
'paymentMethod': _getString('payment_method'),
'passengerWalletBurc': _getString('passenger_wallet_burc'),
'timeOfOrder': _getString('time_of_order'),
'totalPassenger': _getString('total_passenger'),
'carType': _getString('car_type'),
'kazan': _getString('kazan'),
'startNameLocation': _getString('start_name_location'),
'endNameLocation': _getString('end_name_location'),
// --- Special Handling ---
// Steps (handle null values by providing an empty string)
'step0': _getString('step0'),
'step1': _getString('step1'),
'step2': _getString('step2'),
'step3': _getString('step3'),
'step4': _getString('step4'),
// Boolean conversion (1/0 from server to 'true'/'false' string for the app)
'WalletChecked': (serverData['wallet_checked'] == 1).toString(),
// Logic-based conversion for isHaveSteps
// Your app's `rideArguments` expects 'startEnd', so we provide that if has_steps is 1.
// You might need to adjust this logic if 'haveSteps' is also a possibility.
'isHaveSteps': (serverData['has_steps'] == 1)
? 'startEnd'
: 'noSteps', // Providing a default
};
}
void _sendAcceptanceNotification(String? customerToken, rideId) {
try {
if (customerToken == null) return;
final FirebaseMessagesController _firebaseMessagesController =
Get.put(FirebaseMessagesController());
_log("Attempting to send acceptance notification to passenger...");
List<String> bodyToPassenger = [
box.read(BoxName.driverID).toString(),
box.read(BoxName.nameDriver).toString(),
box.read(BoxName.tokenDriver).toString(),
rideId.toString()
];
// Safely check for customer token
final String? token = customerToken;
if (token != null && token.isNotEmpty) {
_firebaseMessagesController.sendNotificationToDriverMAP('Accepted Ride',
'your ride is applied'.tr, token, bodyToPassenger, 'start.wav');
_log("Acceptance notification task was fired.");
} else {
_log("Could not send notification: Customer token is missing or empty.");
}
} catch (e) {
_log("Error while firing notification task: $e");
}
}

View File

@@ -51,7 +51,7 @@ import 'package:get/get.dart';
// child: Padding( // child: Padding(
// padding: const EdgeInsets.all(14), // padding: const EdgeInsets.all(14),
// child: Text( // child: Text(
// "We have maintenance offers for your car. You can use them after completing 600 trips to get a 20% discount on car repairs. Enjoy using our SEFER app and be part of our SEFER family." // "We have maintenance offers for your car. You can use them after completing 600 trips to get a 20% discount on car repairs. Enjoy using our Tripz app and be part of our Tripz family."
// .tr, // .tr,
// style: AppStyle.title, // style: AppStyle.title,
// ), // ),
@@ -186,7 +186,7 @@ class MaintainCenterPage extends StatelessWidget {
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
Text( Text(
"We have maintenance offers for your car. You can use them after completing 600 trips to get a 20% discount on car repairs. Enjoy using our SEFER app and be part of our SEFER family." "We have maintenance offers for your car. You can use them after completing 600 trips to get a 20% discount on car repairs. Enjoy using our Tripz app and be part of our Tripz family."
.tr, .tr,
style: Theme.of(context) style: Theme.of(context)
.textTheme .textTheme

View File

@@ -13,8 +13,11 @@ import 'package:sefer_driver/controller/firebase/firbase_messge.dart';
import 'package:sefer_driver/controller/home/captin/map_driver_controller.dart'; import 'package:sefer_driver/controller/home/captin/map_driver_controller.dart';
import 'package:sefer_driver/views/widgets/elevated_btn.dart'; import 'package:sefer_driver/views/widgets/elevated_btn.dart';
import '../../../../constant/box_name.dart';
import '../../../../constant/style.dart'; import '../../../../constant/style.dart';
import '../../../../controller/functions/launch.dart'; import '../../../../controller/functions/launch.dart';
import '../../../../main.dart';
import '../../../../print.dart';
class PassengerInfoWindow extends StatelessWidget { class PassengerInfoWindow extends StatelessWidget {
const PassengerInfoWindow({super.key}); const PassengerInfoWindow({super.key});
@@ -179,7 +182,7 @@ class PassengerInfoWindow extends StatelessWidget {
if (await controller if (await controller
.calculateDistanceBetweenDriverAndPassengerLocation() < .calculateDistanceBetweenDriverAndPassengerLocation() <
140) { 140) {
FirebaseMessagesController() Get.find<FirebaseMessagesController>()
.sendNotificationToDriverMAP( .sendNotificationToDriverMAP(
'Hi ,I Arrive your site', 'Hi ,I Arrive your site',
'I Arrive at your site'.tr, 'I Arrive at your site'.tr,
@@ -245,7 +248,7 @@ class PassengerInfoWindow extends StatelessWidget {
MyDialog().getDialog( MyDialog().getDialog(
'Are you sure to cancel?'.tr, '', 'Are you sure to cancel?'.tr, '',
() async { () async {
FirebaseMessagesController() Get.find<FirebaseMessagesController>()
.sendNotificationToDriverMAP( .sendNotificationToDriverMAP(
'Driver Cancelled Your Trip', 'Driver Cancelled Your Trip',
'You will need to pay the cost to the driver, or it will be deducted from your next trip' 'You will need to pay the cost to the driver, or it will be deducted from your next trip'
@@ -254,6 +257,9 @@ class PassengerInfoWindow extends StatelessWidget {
[], [],
'cancel.wav', 'cancel.wav',
); );
Log.print(
'rideStatus from passenge info 261 : ${box.read(BoxName.rideStatus)}');
box.write(BoxName.rideStatus, 'Cancel');
await controller await controller
.addWaitingTimeCostFromPassengerToDriverWallet(); .addWaitingTimeCostFromPassengerToDriverWallet();
controller.isdriverWaitTimeEnd = false; controller.isdriverWaitTimeEnd = false;
@@ -296,7 +302,7 @@ class PassengerInfoWindow extends StatelessWidget {
_buildMessageTile( _buildMessageTile(
text: "Where are you, sir?".tr, text: "Where are you, sir?".tr,
onTap: () { onTap: () {
FirebaseMessagesController().sendNotificationToDriverMAP( Get.find<FirebaseMessagesController>().sendNotificationToDriverMAP(
'message From Driver', 'message From Driver',
"Where are you, sir?".tr, "Where are you, sir?".tr,
controller.tokenPassenger, controller.tokenPassenger,
@@ -309,7 +315,7 @@ class PassengerInfoWindow extends StatelessWidget {
_buildMessageTile( _buildMessageTile(
text: "I've been trying to reach you but your phone is off.".tr, text: "I've been trying to reach you but your phone is off.".tr,
onTap: () { onTap: () {
FirebaseMessagesController().sendNotificationToDriverMAP( Get.find<FirebaseMessagesController>().sendNotificationToDriverMAP(
'message From Driver', 'message From Driver',
"I've been trying to reach you but your phone is off.".tr, "I've been trying to reach you but your phone is off.".tr,
controller.tokenPassenger, controller.tokenPassenger,
@@ -324,7 +330,7 @@ class PassengerInfoWindow extends StatelessWidget {
"Please don't be late, I'm waiting for you at the specified location." "Please don't be late, I'm waiting for you at the specified location."
.tr, .tr,
onTap: () { onTap: () {
FirebaseMessagesController().sendNotificationToDriverMAP( Get.find<FirebaseMessagesController>().sendNotificationToDriverMAP(
'message From Driver', 'message From Driver',
"Please don't be late, I'm waiting for you at the specified location." "Please don't be late, I'm waiting for you at the specified location."
.tr, .tr,
@@ -338,7 +344,7 @@ class PassengerInfoWindow extends StatelessWidget {
_buildMessageTile( _buildMessageTile(
text: "Please don't be late".tr, text: "Please don't be late".tr,
onTap: () { onTap: () {
FirebaseMessagesController().sendNotificationToDriverMAP( Get.find<FirebaseMessagesController>().sendNotificationToDriverMAP(
'message From Driver', 'message From Driver',
"Please don't be late".tr, "Please don't be late".tr,
controller.tokenPassenger, controller.tokenPassenger,
@@ -364,7 +370,8 @@ class PassengerInfoWindow extends StatelessWidget {
), ),
IconButton( IconButton(
onPressed: () { onPressed: () {
FirebaseMessagesController().sendNotificationToDriverMAP( Get.find<FirebaseMessagesController>()
.sendNotificationToDriverMAP(
'message From Driver', 'message From Driver',
controller.messageToPassenger.text, controller.messageToPassenger.text,
controller.tokenPassenger, controller.tokenPassenger,

View File

@@ -171,7 +171,7 @@ class SosConnect extends StatelessWidget {
} else { } else {
throw 'Could not launch google maps'; throw 'Could not launch google maps';
} }
}; }();
} }
void _sendWhatsAppMessage(MapDriverController mapDriverController) { void _sendWhatsAppMessage(MapDriverController mapDriverController) {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,5 @@
import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:sefer_driver/constant/colors.dart'; import 'package:sefer_driver/constant/colors.dart';
@@ -5,9 +7,13 @@ import 'package:sefer_driver/constant/style.dart';
import 'package:sefer_driver/controller/home/payment/captain_wallet_controller.dart'; import 'package:sefer_driver/controller/home/payment/captain_wallet_controller.dart';
import 'package:sefer_driver/controller/payment/payment_controller.dart'; import 'package:sefer_driver/controller/payment/payment_controller.dart';
import 'package:sefer_driver/views/widgets/mydialoug.dart'; import 'package:sefer_driver/views/widgets/mydialoug.dart';
import 'package:webview_flutter/webview_flutter.dart';
import '../../../constant/box_name.dart'; import '../../../constant/box_name.dart';
import '../../../constant/links.dart';
import '../../../controller/functions/crud.dart';
import '../../../main.dart'; import '../../../main.dart';
import '../../../print.dart';
import '../../widgets/elevated_btn.dart'; import '../../widgets/elevated_btn.dart';
import '../../widgets/my_textField.dart'; import '../../widgets/my_textField.dart';
@@ -44,21 +50,34 @@ class PointsCaptain extends StatelessWidget {
title: 'Pay with Credit Card'.tr, title: 'Pay with Credit Card'.tr,
onPressed: () async { onPressed: () async {
Get.back(); Get.back();
await paymentController.payWithPayMob(
context, var res = await CRUD().postWallet(
pricePoint.toStringAsFixed(2), // link: AppLink.payWithPayMobWalletPasenger,
box.read(BoxName.countryCode) == 'Egypt' link: AppLink.payWithPayMobCardDriver,
? 'EGP' payload: {
: 'JOD', () async { "amount": pricePoint.toStringAsFixed(2),
// await captainWalletController.getPaymentId( "email": box.read(BoxName.emailDriver),
// 'visa-in', pricePoint); "first_name": (box
await captainWalletController.addDriverWallet( .read(BoxName.nameDriver)
'visa-in', countPoint, pricePoint); .toString()
await captainWalletController.addSeferWallet( .split(' ')[0])
'visa-in', pricePoint.toString()); .toString(),
await captainWalletController "last_name": (box
.getCaptainWalletFromBuyPoints(); .read(BoxName.nameDriver)
.toString()
.split(' ')[1])
.toString(),
"phone_number": (box.read(BoxName.phoneDriver)),
}); });
// var d = jsonDecode(res);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PaymentScreen(
iframeUrl: res['message'],
countPrice: countPoint.toString()),
),
);
}, //51524 }, //51524
), ),
// Add some spacing between buttons // Add some spacing between buttons
@@ -88,31 +107,45 @@ class PointsCaptain extends StatelessWidget {
BoxName.phoneWallet, BoxName.phoneWallet,
paymentController paymentController
.walletphoneController.text); .walletphoneController.text);
await paymentController.payWithPayMobWallet( var res = await CRUD().postWallet(
context, // link: AppLink.payWithPayMobWalletPasenger,
link: AppLink.payWithWallet,
payload: {
"amount":
pricePoint.toStringAsFixed(2), pricePoint.toStringAsFixed(2),
box.read(BoxName.countryCode) == 'Egypt' "email":
? 'EGP' box.read(BoxName.emailDriver),
: 'JOD', () async { "first_name": (box
// await captainWalletController .read(BoxName.nameDriver)
// .getPaymentId('visa-in', pricePoint); .toString()
await captainWalletController .split(' ')[0])
.addDriverWallet('visa-in', .toString(),
countPoint, pricePoint); "last_name": (box
await captainWalletController .read(BoxName.nameDriver)
.addSeferWallet( .toString()
'visa-in', pricePoint.toString()); .split(' ')[1])
await captainWalletController .toString(),
.getCaptainWalletFromBuyPoints(); "phone_number":
(box.read(BoxName.phoneWallet)),
}); });
} Navigator.push(
MyDialog().getDialog( context,
'phone number is wrong'.tr, MaterialPageRoute(
'', builder: (context) =>
() { PaymentScreenWallet(
Get.back(); iframeUrl: res['message'],
}, countPrice:
countPoint.toString()),
),
); );
}
// MyDialog().getDialog(
// 'phone number is wrong'.tr,
// '',
// () {
// Get.back();
// },
// );
// Get.back(); // Get.back();
})); }));
}, },
@@ -173,3 +206,311 @@ class PointsCaptain extends StatelessWidget {
); );
} }
} }
class PaymentScreen extends StatefulWidget {
final String iframeUrl;
final String countPrice;
const PaymentScreen(
{required this.iframeUrl, Key? key, required this.countPrice})
: super(key: key);
@override
State<PaymentScreen> createState() => _PaymentScreenState();
}
class _PaymentScreenState extends State<PaymentScreen> {
late final WebViewController _controller;
final controller = Get.find<CaptainWalletController>();
@override
void initState() {
super.initState();
_controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setNavigationDelegate(NavigationDelegate(
onPageFinished: (url) {
if (url.contains("success")) {
_fetchPaymentStatus(); // ✅ استدعاء الويب هوك بعد نجاح الدفع
} else if (url.contains("failed")) {
showCustomDialog(
title: "Error".tr,
message: 'Payment Failed'.tr, // يتم جلب رسالة الخطأ من الخادم
isSuccess: false,
);
}
},
))
..loadRequest(Uri.parse(widget.iframeUrl));
}
Future<void> _fetchPaymentStatus() async {
final String userId = box.read(BoxName.phoneDriver);
await Future.delayed(const Duration(seconds: 2));
try {
final response = await CRUD().postWallet(
link: AppLink.paymetVerifyDriver,
payload: {
'user_id': userId,
'driverID': box.read(BoxName.driverID),
'paymentMethod': 'visa-in',
},
);
if (response != 'failure' && response != 'token_expired') {
if (response['status'] == 'success') {
final payment = response['message'];
final amount = payment['amount'].toString();
final bonus = payment['bonus'].toString();
final paymentID = payment['paymentID'].toString();
await controller.getCaptainWalletFromBuyPoints();
showCustomDialog(
title: "payment_success".tr,
message:
"${"transaction_id".tr}: $paymentID\n${"amount_paid".tr}: $amount EGP\n${"bonus_added".tr}: $bonus ${"points".tr}",
isSuccess: true,
);
} else {
showCustomDialog(
title: "transaction_failed".tr,
message: response['message'].toString(),
isSuccess: false,
);
}
} else {
showCustomDialog(
title: "connection_failed".tr,
message: response.toString(),
isSuccess: false,
);
}
} catch (e) {
showCustomDialog(
title: "server_error".tr,
message: "server_error_message".tr,
isSuccess: false,
);
}
}
void showCustomDialog({
required String title,
required String message,
required bool isSuccess,
}) {
showDialog(
barrierDismissible: false,
context: Get.context!,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
title: Row(
children: [
Icon(
isSuccess ? Icons.check_circle : Icons.error,
color: isSuccess ? Colors.green : Colors.red,
),
const SizedBox(width: 8),
Text(
title,
style: TextStyle(
color: isSuccess ? Colors.green : Colors.red,
fontWeight: FontWeight.bold,
),
),
],
),
content: Text(
message,
style: const TextStyle(fontSize: 16),
),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context);
Navigator.pop(context);
},
style: TextButton.styleFrom(
backgroundColor: isSuccess ? Colors.green : Colors.red,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
),
child: Text(
"OK",
style: const TextStyle(color: Colors.white),
),
),
],
);
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('إتمام الدفع')),
body: WebViewWidget(controller: _controller),
);
}
}
class PaymentScreenWallet extends StatefulWidget {
final String iframeUrl;
final String countPrice;
const PaymentScreenWallet(
{required this.iframeUrl, Key? key, required this.countPrice})
: super(key: key);
@override
State<PaymentScreenWallet> createState() => _PaymentScreenWalletState();
}
class _PaymentScreenWalletState extends State<PaymentScreenWallet> {
late final WebViewController _controller;
final controller = Get.find<CaptainWalletController>();
@override
void initState() {
super.initState();
_controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setNavigationDelegate(NavigationDelegate(
onPageFinished: (url) {
if (url.contains("success")) {
_fetchPaymentStatus(); // ✅ استدعاء الويب هوك بعد نجاح الدفع
} else if (url.contains("failed")) {
showCustomDialog(
title: "Error".tr,
message: 'Payment Failed'.tr, // يتم جلب رسالة الخطأ من الخادم
isSuccess: false,
);
}
},
))
..loadRequest(Uri.parse(widget.iframeUrl));
}
Future<void> _fetchPaymentStatus() async {
final String userId = '+2' + box.read(BoxName.phoneWallet);
await Future.delayed(const Duration(seconds: 2));
try {
final response = await CRUD().postWallet(
link: AppLink.paymetVerifyDriver,
payload: {
'user_id': userId,
'driverID': box.read(BoxName.driverID),
'paymentMethod': 'visa-in',
},
);
if (response != 'failure' && response != 'token_expired') {
if (response['status'] == 'success') {
final payment = response['message'];
final amount = payment['amount'].toString();
final bonus = payment['bonus'].toString();
final paymentID = payment['paymentID'].toString();
await controller.getCaptainWalletFromBuyPoints();
showCustomDialog(
title: "payment_success".tr,
message:
"${"transaction_id".tr}: $paymentID\n${"amount_paid".tr}: $amount EGP\n${"bonus_added".tr}: $bonus ${"points".tr}",
isSuccess: true,
);
} else {
showCustomDialog(
title: "transaction_failed".tr,
message: response['message'].toString(),
isSuccess: false,
);
}
} else {
showCustomDialog(
title: "connection_failed".tr,
message: response.toString(),
isSuccess: false,
);
}
} catch (e) {
showCustomDialog(
title: "server_error".tr,
message: "server_error_message".tr,
isSuccess: false,
);
}
}
void showCustomDialog({
required String title,
required String message,
required bool isSuccess,
}) {
showDialog(
barrierDismissible: false,
context: Get.context!,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
title: Row(
children: [
Icon(
isSuccess ? Icons.check_circle : Icons.error,
color: isSuccess ? Colors.green : Colors.red,
),
const SizedBox(width: 8),
Text(
title,
style: TextStyle(
color: isSuccess ? Colors.green : Colors.red,
fontWeight: FontWeight.bold,
),
),
],
),
content: Text(
message,
style: const TextStyle(fontSize: 16),
),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context);
Navigator.pop(context);
},
style: TextButton.styleFrom(
backgroundColor: isSuccess ? Colors.green : Colors.red,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
),
child: Text(
"OK",
style: const TextStyle(color: Colors.white),
),
),
],
);
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('إتمام الدفع')),
body: WebViewWidget(controller: _controller),
);
}
}

View File

@@ -93,6 +93,7 @@ dependencies:
jwt_decoder: ^2.0.1 jwt_decoder: ^2.0.1
jailbreak_root_detection: ^1.1.5 jailbreak_root_detection: ^1.1.5
device_info_plus: ^11.3.0 device_info_plus: ^11.3.0
# flutter_isolate: ^2.1.0
# lingo_hunter: ^1.0.3 # lingo_hunter: ^1.0.3
dev_dependencies: dev_dependencies: