25-6-23/1
This commit is contained in:
14
.env
14
.env
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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>
|
||||||
@@ -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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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";
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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']
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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');
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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(),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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({
|
||||||
|
|||||||
@@ -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(),
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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 {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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)}',
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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": "لا، أنا عاوز",
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
223
lib/main.dart
223
lib/main.dart
@@ -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),
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
13
lib/models/overlay_service.dart
Normal file
13
lib/models/overlay_service.dart
Normal 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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -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()),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -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,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
@@ -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),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user