finished checkout ui
|
|
@ -35,6 +35,9 @@ android {
|
||||||
// TODO: Add your own signing config for the release build.
|
// TODO: Add your own signing config for the release build.
|
||||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||||
signingConfig = signingConfigs.getByName("debug")
|
signingConfig = signingConfigs.getByName("debug")
|
||||||
|
isMinifyEnabled = false
|
||||||
|
isShrinkResources = false
|
||||||
|
// proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
# Flutter related
|
||||||
|
-keep class io.flutter.app.** { *; }
|
||||||
|
-keep class io.flutter.plugin.** { *; }
|
||||||
|
-keep class io.flutter.util.** { *; }
|
||||||
|
-keep class io.flutter.view.** { *; }
|
||||||
|
-keep class io.flutter.** { *; }
|
||||||
|
-keep class io.flutter.plugins.** { *; }
|
||||||
|
-keep class io.flutter.embedding.** { *; }
|
||||||
|
|
||||||
|
# Mobile Scanner
|
||||||
|
-keep class com.google.mlkit.** { *; }
|
||||||
|
-keep class com.google.android.gms.** { *; }
|
||||||
|
|
||||||
|
# Geolocator
|
||||||
|
-keep class com.baseflow.geolocator.** { *; }
|
||||||
|
|
||||||
|
# Image Picker
|
||||||
|
-keep class io.flutter.plugins.imagepicker.** { *; }
|
||||||
|
|
||||||
|
# Permission Handler
|
||||||
|
-keep class com.baseflow.permissionhandler.** { *; }
|
||||||
|
|
||||||
|
# Keep native methods
|
||||||
|
-keepclasseswithmembernames class * {
|
||||||
|
native <methods>;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Keep Parcelable implementations
|
||||||
|
-keep class * implements android.os.Parcelable {
|
||||||
|
public static final android.os.Parcelable$Creator *;
|
||||||
|
}
|
||||||
|
|
||||||
|
# General warnings
|
||||||
|
-dontwarn com.google.android.gms.**
|
||||||
|
-dontwarn com.google.mlkit.**
|
||||||
|
-dontwarn java.lang.invoke.**
|
||||||
|
|
||||||
|
# Keep annotations
|
||||||
|
-keepattributes *Annotation*
|
||||||
|
-keepattributes Signature
|
||||||
|
-keepattributes InnerClasses
|
||||||
|
-keepattributes EnclosingMethod
|
||||||
|
|
@ -3,6 +3,11 @@
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
||||||
|
<uses-permission android:name="android.permission.CAMERA"/>
|
||||||
|
<uses-permission android:name="android.permission.FLASHLIGHT"/>
|
||||||
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||||
|
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
|
||||||
<application
|
<application
|
||||||
android:label="lba"
|
android:label="lba"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="20" height="23" viewBox="0 0 20 23" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M5.79224 1.76514L5.94263 1.76904C6.24289 1.78418 6.53574 1.84464 6.80981 1.9624L6.94556 2.02588L6.94751 2.02686C7.52647 2.32768 7.82836 2.96179 7.97583 3.65576C8.12678 4.36612 8.13138 5.22393 8.07544 6.02197V6.02393C8.03105 6.63131 7.94887 7.21978 7.86548 7.71533C7.91576 7.61933 7.96986 7.52238 8.02563 7.42529L8.02661 7.42432C8.22577 7.08032 8.46597 6.73421 8.72192 6.46338L8.83911 6.34619C9.09737 6.10782 9.41035 5.91116 9.76685 5.89795L9.92212 5.90381L9.92896 5.90479C10.0597 5.92155 10.202 5.96176 10.3372 6.05713C10.4654 6.14765 10.5499 6.26228 10.6106 6.35986C10.719 6.53433 10.7929 6.75607 10.8381 6.98877L10.8743 7.22412L10.8928 7.46826C10.9202 8.0492 10.8336 8.70309 10.7327 9.16455C10.6634 9.48235 10.5788 9.80507 10.4915 10.1147L10.3948 10.4536L10.4817 10.5298L10.4846 10.5327C10.7889 10.8183 11.0717 11.2207 11.2981 11.6118H11.2991C11.3585 11.7148 11.4139 11.8187 11.467 11.9204C11.3818 11.4183 11.2981 10.8186 11.2532 10.1987V10.1978C11.1972 9.3984 11.2021 8.54046 11.3528 7.82568V7.82471C11.5004 7.1288 11.8027 6.49493 12.385 6.19189L12.387 6.19092C12.7436 6.0075 13.1412 5.92823 13.5452 5.92822C13.5935 5.92822 13.659 5.9285 13.7317 5.93408H13.7307C14.4925 5.97701 15.3119 6.27804 16.0413 6.73877C16.6321 7.10937 17.1678 7.58674 17.5813 8.09619C17.9388 8.53671 18.2249 9.02663 18.3596 9.51514L18.4084 9.72412V9.7251C19.0046 12.9738 18.0159 15.7451 16.595 18.2964L16.5637 18.3511L16.5608 18.7729L16.5452 20.5581L16.5413 21.0532H16.0452C15.7823 21.0532 15.5232 21.0495 15.2678 21.0415L14.7571 21.0259V21.0239L14.5637 21.0181C14.2046 21.0061 13.8489 20.9865 13.4973 20.9585L13.2483 20.938L13.2473 20.9448L12.7854 20.8989C12.4233 20.8631 12.0565 20.8189 11.6936 20.7671L11.4749 20.7349L11.4739 20.7417L11.2375 20.7017L11.176 20.6929V20.6909L10.9895 20.6597C10.6582 20.6038 10.3232 20.54 9.98462 20.4683L9.47681 20.3608L9.60278 19.8569L10.0403 18.1147L10.1194 17.8003L10.0813 17.7153C9.99992 17.5341 9.75845 16.9846 9.48071 16.2544L9.20044 16.313C8.91032 16.3726 8.61451 16.4279 8.32153 16.4761L8.13501 16.5063L8.13599 16.5093L8.02661 16.5249L7.83911 16.5562L7.83813 16.5513L7.62036 16.5835C7.26078 16.6354 6.89391 16.6795 6.52759 16.7153L6.36646 16.73L6.36841 16.7378L6.13599 16.7524L6.0647 16.7603L6.06372 16.7573L5.81274 16.7749C5.46187 16.7986 5.11219 16.8186 4.74927 16.8306L4.55981 16.8364L4.56079 16.8384L4.04907 16.854C3.79007 16.862 3.53313 16.8657 3.27173 16.8657H2.77563L2.77173 16.3696L2.75708 14.5532L2.75317 14.0815C1.34048 11.5427 0.350982 8.78214 0.94751 5.54443C1.04992 4.9897 1.36454 4.4234 1.77173 3.92139C2.18354 3.41372 2.71678 2.9379 3.30591 2.56885C4.03019 2.11334 4.84597 1.81368 5.60474 1.77197V1.771H5.60767C5.61089 1.77082 5.61421 1.77018 5.61743 1.77002V1.771C5.68512 1.76635 5.74575 1.76514 5.79126 1.76514H5.79224Z" stroke="#70706E"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.8 KiB |
|
|
@ -0,0 +1,4 @@
|
||||||
|
<svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M8.21197 9.5L4.27897 16.975C2.45797 20.436 10.079 21.5 12 21.5C13.921 21.5 21.542 20.436 19.721 16.975L15.788 9.5" stroke="#70706E" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M10.134 12.72C10.804 12.355 11.39 12.503 11.741 12.737C11.886 12.834 11.958 12.882 12 12.882C12.042 12.882 12.114 12.834 12.259 12.737C12.61 12.503 13.195 12.355 13.866 12.721C14.746 13.201 14.945 14.783 12.916 16.118C12.529 16.373 12.336 16.5 12 16.5C11.665 16.5 11.471 16.373 11.085 16.118C9.05498 14.783 9.25498 13.201 10.135 12.721M6.99998 11.314C4.99998 12.291 1.47398 9.131 2.06598 8.374L5.56998 3.89C5.75998 3.646 6.07198 3.5 6.40398 3.5H8.50698C8.62362 3.50061 8.73726 3.53699 8.83257 3.60422C8.92789 3.67146 9.00028 3.76632 9.03998 3.876C9.42298 4.943 10.762 6.223 12 6.223C13.238 6.223 14.577 4.943 14.96 3.876C14.9997 3.76632 15.0721 3.67146 15.1674 3.60422C15.2627 3.53699 15.3763 3.50061 15.493 3.5H17.596C17.928 3.5 18.239 3.646 18.43 3.89L21.934 8.373C22.526 9.131 19 12.291 17.002 11.314" stroke="#70706E" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
|
|
@ -0,0 +1,14 @@
|
||||||
|
<svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.43994 4.28296C9.57255 4.28296 9.69973 4.33564 9.7935 4.42941C9.88726 4.52317 9.93994 4.65035 9.93994 4.78296V8.08296C9.93994 8.21557 9.88726 8.34274 9.7935 8.43651C9.69973 8.53028 9.57255 8.58296 9.43994 8.58296C9.30733 8.58296 9.18016 8.53028 9.08639 8.43651C8.99262 8.34274 8.93994 8.21557 8.93994 8.08296V4.78296C8.93994 4.65035 8.99262 4.52317 9.08639 4.42941C9.18016 4.33564 9.30733 4.28296 9.43994 4.28296Z" fill="#70706E"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.88995 7.45257C6.45495 7.31757 7.03146 7.42007 7.62995 7.72907C8.11746 7.98157 8.46345 8.09707 8.73295 8.15257C9.00195 8.20857 9.21595 8.20957 9.47445 8.20957V9.20957H9.46446C9.20646 9.20957 8.90446 9.20957 8.53046 9.13207C8.15196 9.05357 7.71945 8.90107 7.17045 8.61707C6.73145 8.39057 6.40045 8.35857 6.12245 8.42507C5.83045 8.49507 5.52195 8.69007 5.16645 9.05707C4.35045 9.90107 4.09695 10.7701 4.00845 11.4381C3.95845 12.2601 4.10695 13.8831 4.84245 15.4696C5.09245 16.0096 5.44745 16.7546 5.88045 17.3381C6.09645 17.6291 6.31345 17.8531 6.52195 17.9911C6.72445 18.1246 6.89245 18.1611 7.04495 18.1351C8.60645 17.8661 8.89995 17.8596 9.20445 17.8596H9.72295V18.8596H9.18995C8.97895 18.8596 8.72995 18.8596 7.21495 19.1206C6.74495 19.2016 6.32146 19.0571 5.97095 18.8256C5.62645 18.5981 5.32895 18.2726 5.07745 17.9341C4.57495 17.2576 4.18195 16.4221 3.93545 15.8901C3.11645 14.1241 2.94945 12.3216 3.01145 11.3581L3.01295 11.3421L3.01495 11.3261C3.12095 10.5041 3.43695 9.40657 4.44795 8.36207C4.87045 7.92507 5.33945 7.58407 5.89045 7.45207" fill="#70706E"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.32 6.205C8.068 6.9205 8.4735 7.788 8.4735 8.46C8.4735 8.59261 8.52618 8.71979 8.61994 8.81355C8.71371 8.90732 8.84089 8.96 8.9735 8.96C9.10611 8.96 9.23328 8.90732 9.32705 8.81355C9.42082 8.71979 9.4735 8.59261 9.4735 8.46C9.4735 7.435 8.8895 6.3225 8.011 5.482C7.122 4.6325 5.8715 4 4.448 4C4.31539 4 4.18821 4.05268 4.09444 4.14645C4.00068 4.24021 3.948 4.36739 3.948 4.5C3.948 4.63261 4.00068 4.75979 4.09444 4.85355C4.18821 4.94732 4.31539 5 4.448 5C5.57 5 6.582 5.4995 7.3195 6.205" fill="#70706E"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.28697 4.00458C4.41851 3.98817 4.55118 4.02467 4.65582 4.10606C4.76045 4.18744 4.82849 4.30705 4.84497 4.43858C5.09097 6.40358 6.81747 7.43858 8.21197 7.99608C8.33509 8.04534 8.43361 8.1415 8.48584 8.2634C8.53806 8.3853 8.53973 8.52295 8.49047 8.64608C8.4412 8.76921 8.34504 8.86772 8.22315 8.91995C8.10125 8.97218 7.96359 8.97384 7.84047 8.92458C6.40597 8.35108 4.17297 7.12258 3.85297 4.56258C3.83656 4.43104 3.87306 4.29837 3.95445 4.19373C4.03583 4.08909 4.15544 4.02106 4.28697 4.00458ZM12.881 7.45158C12.305 7.31958 11.714 7.41858 11.096 7.72558C10.586 7.97858 10.2225 8.09558 9.93747 8.15208C9.65247 8.20858 9.42647 8.20958 9.15747 8.20958C9.02486 8.20958 8.89768 8.26226 8.80391 8.35602C8.71014 8.44979 8.65747 8.57697 8.65747 8.70958C8.65747 8.84219 8.71014 8.96936 8.80391 9.06313C8.89768 9.1569 9.02486 9.20958 9.15747 9.20958H9.16697C9.43547 9.20958 9.74697 9.20958 10.132 9.13308C10.5225 9.05558 10.97 8.90408 11.54 8.62108C12.002 8.39208 12.356 8.35708 12.658 8.42608C12.971 8.49808 13.2965 8.69708 13.6665 9.06458C14.5245 9.91608 14.784 10.7906 14.8735 11.4566C14.8929 11.5864 14.9626 11.7034 15.0676 11.7823C15.1726 11.8612 15.3043 11.8956 15.4345 11.8781C15.5646 11.8607 15.6826 11.7927 15.7631 11.689C15.8435 11.5852 15.88 11.454 15.8645 11.3236C15.7535 10.4971 15.4225 9.39858 14.371 8.35458C13.9305 7.91758 13.446 7.58058 12.881 7.45158ZM13.3535 17.6401C13.3062 17.5945 13.2503 17.5588 13.1892 17.5348C13.1281 17.5108 13.0628 17.4991 12.9972 17.5004C12.9315 17.5016 12.8668 17.5158 12.8066 17.5421C12.7464 17.5684 12.692 17.6063 12.6465 17.6536C12.268 18.0466 11.95 18.1786 11.681 18.1346C10.055 17.8656 9.75097 17.8596 9.43847 17.8596C9.30586 17.8596 9.17868 17.9123 9.08491 18.006C8.99115 18.0998 8.93847 18.227 8.93847 18.3596C8.93847 18.4922 8.99115 18.6194 9.08491 18.7131C9.17868 18.8069 9.30586 18.8596 9.43847 18.8596H9.45247C9.67597 18.8596 9.93597 18.8596 11.5175 19.1211C12.2785 19.2471 12.91 18.8211 13.367 18.3471C13.4126 18.2998 13.4484 18.2439 13.4724 18.1827C13.4964 18.1216 13.5082 18.0562 13.5069 17.9905C13.5056 17.9248 13.4914 17.86 13.4651 17.7998C13.4388 17.7396 13.4009 17.6856 13.3535 17.6401Z" fill="#70706E"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.325 8.55162C15.8235 9.45662 15.6935 10.4061 15.893 11.0476C15.9125 11.1103 15.9195 11.1763 15.9135 11.2417C15.9075 11.307 15.8887 11.3706 15.8582 11.4288C15.8276 11.4869 15.7859 11.5384 15.7354 11.5804C15.685 11.6225 15.6267 11.6541 15.564 11.6736C15.5013 11.6931 15.4354 11.7001 15.37 11.6941C15.3046 11.6881 15.241 11.6693 15.1829 11.6388C15.1247 11.6082 15.0732 11.5665 15.0312 11.516C14.9892 11.4656 14.9575 11.4073 14.938 11.3446C14.6335 10.3651 14.8615 9.12962 15.4505 8.06662C16.047 6.99062 17.0535 6.01612 18.413 5.59312C18.4757 5.57361 18.5416 5.56665 18.607 5.57263C18.6724 5.57861 18.736 5.59742 18.7941 5.62797C18.8523 5.65852 18.9038 5.70022 18.9458 5.75069C18.9878 5.80116 19.0195 5.85941 19.039 5.92212C19.0585 5.98482 19.0655 6.05075 19.0595 6.11615C19.0535 6.18155 19.0347 6.24512 19.0042 6.30325C18.9736 6.36138 18.9319 6.41293 18.8814 6.45494C18.831 6.49695 18.7727 6.52861 18.71 6.54812C17.6385 6.88112 16.82 7.65912 16.325 8.55162Z" fill="#70706E"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.3595 9.18958C16.7755 10.0446 15.9855 10.5861 15.323 10.6961C15.2574 10.7059 15.1944 10.7286 15.1377 10.763C15.081 10.7973 15.0316 10.8426 14.9926 10.8962C14.9535 10.9498 14.9255 11.0107 14.9102 11.0752C14.8949 11.1398 14.8926 11.2067 14.9034 11.2721C14.9142 11.3376 14.938 11.4002 14.9732 11.4564C15.0085 11.5126 15.0545 11.5612 15.1088 11.5994C15.163 11.6376 15.2243 11.6646 15.289 11.6789C15.3538 11.6932 15.4208 11.6944 15.486 11.6826C16.4975 11.5151 17.4995 10.7571 18.185 9.75358C18.879 8.73758 19.2985 7.40058 19.066 5.99608C19.0553 5.93127 19.0319 5.86921 18.9973 5.81343C18.9626 5.75765 18.9172 5.70925 18.8638 5.67099C18.8104 5.63273 18.75 5.60537 18.6861 5.59045C18.6221 5.57554 18.5558 5.57337 18.491 5.58408C18.4262 5.59478 18.3641 5.61814 18.3084 5.65283C18.2526 5.68752 18.2042 5.73286 18.1659 5.78625C18.1277 5.83964 18.1003 5.90005 18.0854 5.96402C18.0705 6.02799 18.0683 6.09427 18.079 6.15908C18.2625 7.26608 17.935 8.34658 17.359 9.18908" fill="#70706E"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.89 12C15.5585 12 15.2406 12.1317 15.0061 12.3661C14.7717 12.6005 14.64 12.9185 14.64 13.25C14.64 13.5815 14.7717 13.8995 15.0061 14.1339C15.2406 14.3683 15.5585 14.5 15.89 14.5C16.2215 14.5 16.5395 14.3683 16.7739 14.1339C17.0083 13.8995 17.14 13.5815 17.14 13.25C17.14 12.9185 17.0083 12.6005 16.7739 12.3661C16.5395 12.1317 16.2215 12 15.89 12ZM13.64 13.25C13.64 12.9545 13.6982 12.6619 13.8113 12.389C13.9244 12.116 14.0901 11.8679 14.299 11.659C14.508 11.4501 14.756 11.2843 15.029 11.1713C15.302 11.0582 15.5945 11 15.89 11C16.1855 11 16.4781 11.0582 16.7511 11.1713C17.024 11.2843 17.2721 11.4501 17.481 11.659C17.6899 11.8679 17.8557 12.116 17.9687 12.389C18.0818 12.6619 18.14 12.9545 18.14 13.25C18.14 13.8467 17.903 14.419 17.481 14.841C17.059 15.2629 16.4868 15.5 15.89 15.5C15.2933 15.5 14.721 15.2629 14.299 14.841C13.8771 14.419 13.64 13.8467 13.64 13.25Z" fill="#70706E"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.9224 9.54503C19.4841 9.74655 19.9427 10.1629 20.1973 10.7025C20.452 11.2422 20.4819 11.8609 20.2804 12.4225C20.2582 12.4844 20.2241 12.5412 20.18 12.5898C20.1359 12.6385 20.0826 12.6779 20.0232 12.706C19.9638 12.734 19.8995 12.7501 19.8339 12.7533C19.7683 12.7565 19.7027 12.7467 19.6409 12.7245C19.5791 12.7024 19.5222 12.6683 19.4736 12.6241C19.425 12.58 19.3855 12.5267 19.3575 12.4673C19.3294 12.4079 19.3133 12.3436 19.3102 12.278C19.307 12.2124 19.3167 12.1469 19.3389 12.085C19.451 11.773 19.4345 11.4292 19.2931 11.1294C19.1517 10.8295 18.8969 10.5981 18.5849 10.486C18.2729 10.374 17.9291 10.3905 17.6292 10.5319C17.3294 10.6733 17.098 10.928 16.9859 11.24C16.965 11.3034 16.9315 11.3618 16.8876 11.4121C16.8437 11.4623 16.7902 11.5032 16.7302 11.5324C16.6703 11.5616 16.6051 11.5786 16.5385 11.5822C16.4719 11.5858 16.4052 11.5761 16.3424 11.5536C16.2796 11.5311 16.222 11.4962 16.1729 11.4511C16.1238 11.4059 16.0842 11.3514 16.0565 11.2908C16.0287 11.2301 16.0134 11.1645 16.0115 11.0978C16.0095 11.0311 16.0208 10.9647 16.0449 10.9025C16.2465 10.341 16.6629 9.8825 17.2026 9.62792C17.7422 9.37335 18.3608 9.34353 18.9224 9.54503Z" fill="#70706E"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.1265 12.088C18.6384 11.9411 19.1858 11.9806 19.6713 12.1993C20.1568 12.418 20.5491 12.8018 20.7783 13.2825C21.0076 13.7631 21.0589 14.3095 20.9233 14.8245C20.7876 15.3394 20.4738 15.7896 20.0375 16.095C19.9287 16.1676 19.7957 16.1947 19.6672 16.1705C19.5386 16.1462 19.4247 16.0725 19.3498 15.9652C19.2749 15.8579 19.2451 15.7255 19.2668 15.5965C19.2884 15.4674 19.3598 15.352 19.4655 15.275C19.6031 15.1787 19.7199 15.0558 19.8089 14.9134C19.898 14.7711 19.9574 14.6122 19.9837 14.4464C20.01 14.2805 20.0026 14.1111 19.962 13.9482C19.9214 13.7853 19.8483 13.6322 19.7473 13.4981C19.6462 13.3641 19.5191 13.2517 19.3737 13.1678C19.2282 13.0839 19.0674 13.0302 18.9007 13.0098C18.7341 12.9895 18.565 13.0029 18.4036 13.0493C18.2423 13.0957 18.0919 13.1742 17.9615 13.28C17.9106 13.3214 17.8519 13.3524 17.789 13.3712C17.7261 13.3899 17.6601 13.3961 17.5947 13.3894C17.5294 13.3827 17.4661 13.3631 17.4083 13.3319C17.3505 13.3007 17.2994 13.2584 17.258 13.2075C17.2166 13.1565 17.1856 13.0979 17.1668 13.035C17.148 12.972 17.1418 12.906 17.1486 12.8407C17.1553 12.7754 17.1748 12.712 17.206 12.6542C17.2373 12.5965 17.2796 12.5454 17.3305 12.504C17.5652 12.3132 17.8359 12.1717 18.1265 12.088ZM13.89 15C13.5585 15 13.2406 15.1317 13.0061 15.3661C12.7717 15.6005 12.64 15.9184 12.64 16.25C12.64 16.5815 12.7717 16.8994 13.0061 17.1338C13.2406 17.3683 13.5585 17.5 13.89 17.5C14.2215 17.5 14.5395 17.3683 14.7739 17.1338C15.0083 16.8994 15.14 16.5815 15.14 16.25C15.14 15.9184 15.0083 15.6005 14.7739 15.3661C14.5395 15.1317 14.2215 15 13.89 15ZM11.64 16.25C11.64 15.6532 11.8771 15.0809 12.299 14.659C12.721 14.237 13.2933 14 13.89 14C14.4868 14 15.059 14.237 15.481 14.659C15.903 15.0809 16.14 15.6532 16.14 16.25C16.14 16.8467 15.903 17.419 15.481 17.841C15.059 18.2629 14.4868 18.5 13.89 18.5C13.2933 18.5 12.721 18.2629 12.299 17.841C11.8771 17.419 11.64 16.8467 11.64 16.25Z" fill="#70706E"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.89 15C17.5585 15 17.2406 15.1317 17.0061 15.3661C16.7717 15.6005 16.64 15.9185 16.64 16.25C16.64 16.5815 16.7717 16.8995 17.0061 17.1339C17.2406 17.3683 17.5585 17.5 17.89 17.5C18.2215 17.5 18.5395 17.3683 18.7739 17.1339C19.0083 16.8995 19.14 16.5815 19.14 16.25C19.14 15.9185 19.0083 15.6005 18.7739 15.3661C18.5395 15.1317 18.2215 15 17.89 15ZM15.64 16.25C15.64 15.6533 15.8771 15.081 16.299 14.659C16.721 14.2371 17.2933 14 17.89 14C18.4868 14 19.059 14.2371 19.481 14.659C19.903 15.081 20.14 15.6533 20.14 16.25C20.14 16.8467 19.903 17.419 19.481 17.841C19.059 18.2629 18.4868 18.5 17.89 18.5C17.2933 18.5 16.721 18.2629 16.299 17.841C15.8771 17.419 15.64 16.8467 15.64 16.25Z" fill="#70706E"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.89 18C15.5585 18 15.2406 18.1317 15.0061 18.3661C14.7717 18.6005 14.64 18.9185 14.64 19.25C14.64 19.5815 14.7717 19.8995 15.0061 20.1339C15.2406 20.3683 15.5585 20.5 15.89 20.5C16.2215 20.5 16.5395 20.3683 16.7739 20.1339C17.0083 19.8995 17.14 19.5815 17.14 19.25C17.14 18.9185 17.0083 18.6005 16.7739 18.3661C16.5395 18.1317 16.2215 18 15.89 18ZM13.64 19.25C13.64 18.9545 13.6982 18.6619 13.8113 18.389C13.9244 18.116 14.0901 17.8679 14.299 17.659C14.508 17.4501 14.756 17.2843 15.029 17.1713C15.302 17.0582 15.5945 17 15.89 17C16.1855 17 16.4781 17.0582 16.7511 17.1713C17.024 17.2843 17.2721 17.4501 17.481 17.659C17.6899 17.8679 17.8557 18.116 17.9687 18.389C18.0818 18.6619 18.14 18.9545 18.14 19.25C18.14 19.8467 17.903 20.419 17.481 20.841C17.059 21.2629 16.4868 21.5 15.89 21.5C15.2933 21.5 14.721 21.2629 14.299 20.841C13.8771 20.419 13.64 19.8467 13.64 19.25Z" fill="#70706E"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.917 17.483C18.939 17.4211 18.973 17.3642 19.0171 17.3155C19.0611 17.2668 19.1144 17.2272 19.1737 17.1991C19.233 17.171 19.2973 17.1548 19.3629 17.1515C19.4285 17.1482 19.4941 17.1579 19.556 17.18C19.8732 17.2932 20.1609 17.4763 20.3979 17.7156C20.6349 17.9548 20.8152 18.2443 20.9255 18.5626C21.0357 18.8808 21.073 19.2198 21.0348 19.5544C20.9966 19.8891 20.8837 20.2108 20.7045 20.496C20.5253 20.7812 20.2843 21.0225 19.9994 21.2022C19.7145 21.3818 19.3929 21.4952 19.0583 21.534C18.7238 21.5727 18.3847 21.5359 18.0663 21.4262C17.7479 21.3164 17.4581 21.1366 17.2185 20.9C17.1705 20.8541 17.1322 20.7992 17.1056 20.7384C17.0791 20.6776 17.065 20.6121 17.064 20.5458C17.0631 20.4794 17.0753 20.4136 17.1001 20.352C17.1248 20.2905 17.1616 20.2344 17.2082 20.1872C17.2548 20.14 17.3103 20.1026 17.3716 20.077C17.4328 20.0515 17.4985 20.0384 17.5648 20.0385C17.6312 20.0386 17.6968 20.052 17.758 20.0777C17.8191 20.1034 17.8745 20.1411 17.921 20.1885C18.0541 20.3199 18.215 20.4198 18.3919 20.4808C18.5688 20.5418 18.7572 20.5623 18.943 20.5408C19.1289 20.5192 19.3076 20.4563 19.4658 20.3565C19.6241 20.2567 19.758 20.1227 19.8576 19.9643C19.9571 19.8059 20.0199 19.6271 20.0412 19.4412C20.0625 19.2553 20.0417 19.067 19.9805 18.8902C19.9193 18.7134 19.8192 18.5526 19.6876 18.4196C19.556 18.2867 19.3962 18.1849 19.22 18.122C19.1581 18.0999 19.1011 18.0659 19.0523 18.0218C19.0036 17.9777 18.964 17.9244 18.9359 17.865C18.9077 17.8056 18.8916 17.7413 18.8883 17.6756C18.8851 17.61 18.8948 17.5448 18.917 17.483Z" fill="#70706E"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 14 KiB |
|
|
@ -0,0 +1,5 @@
|
||||||
|
<svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M5.94696 9.503C5.94696 9.503 3.68296 11.752 3.01696 11.477C2.07696 11.088 1.67096 7.32 2.30996 6.745L4.76696 4.533C5.89996 3.51 5.92996 3.5 7.43896 3.5H8.95696C9.18296 4.86 10.496 6.492 12 6.492C13.504 6.492 14.816 4.86 15.043 3.5H16.561C18.069 3.5 18.099 3.511 19.233 4.533L21.69 6.745C22.33 7.32 21.923 11.088 20.983 11.477C20.317 11.752 18.049 9.503 18.049 9.503" stroke="#70706E" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M6 8.5V19.027C6 19.732 6.12 20.109 6.755 20.45C9.368 21.85 14.632 21.85 17.245 20.45C17.88 20.11 18 19.732 18 19.027V8.5" stroke="#70706E" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M6 10.5C8 13.167 16 13.167 18 10.5" stroke="#70706E" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 853 B |
|
|
@ -0,0 +1,5 @@
|
||||||
|
<svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M3.53796 17.5H11.05M18.563 17.5H21.067M12.535 5.5C13.198 5.5 13.8339 5.76339 14.3027 6.23223C14.7716 6.70107 15.035 7.33696 15.035 8C15.035 8.66304 14.7716 9.29893 14.3027 9.76777C13.8339 10.2366 13.198 10.5 12.535 10.5C11.8719 10.5 11.236 10.2366 10.7672 9.76777C10.2984 9.29893 10.035 8.66304 10.035 8C10.035 7.33696 10.2984 6.70107 10.7672 6.23223C11.236 5.76339 11.8719 5.5 12.535 5.5ZM12.535 5.5C12.702 5 13.435 3.9 15.035 3.5" stroke="#70706E" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M10.02 8.51493C4.07099 10.7639 1.67199 11.8019 2.03599 12.5459C4.01499 13.4809 7.65099 13.2409 11.371 13.1009C12.395 13.0629 13.405 13.5709 13.637 14.5779C13.801 15.2889 13.845 15.9099 14.168 16.3039C14.353 16.5299 14.668 16.6059 14.95 16.5329C15.71 16.3329 16.025 15.4839 16.4 13.9929C16.473 13.7029 16.577 13.3899 16.859 13.2929C18.119 12.8549 21.998 13.8189 21.998 12.0429C21.935 10.1929 21.262 9.03993 19.099 7.32493C18.4055 6.77136 17.5276 6.50185 16.643 6.57093C15.717 6.64493 15.286 6.76593 15.011 7.00293" stroke="#70706E" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M2.01294 12.493L2.98794 16.798C3.48794 19.052 3.73794 20.179 4.55994 20.84C5.38294 21.5 6.53694 21.5 8.84494 21.5H17.4229C19.1449 21.5 20.0059 21.5 20.5779 20.982C21.1499 20.464 21.2339 19.607 21.4029 17.892L21.9929 12.134" stroke="#70706E" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
|
|
@ -0,0 +1,7 @@
|
||||||
|
<svg width="22" height="23" viewBox="0 0 22 23" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M13.8359 18.375C13.8359 19.8939 12.9486 21.125 11.4297 21.125H5.75781C4.23887 21.125 3.35156 19.8939 3.35156 18.375M14.4375 14.9375C15.1968 14.9375 15.8125 15.7071 15.8125 16.6562C15.8125 17.6054 15.1968 18.375 14.4375 18.375H2.75C1.99074 18.375 1.375 17.6054 1.375 16.6562C1.375 15.7071 1.99074 14.9375 2.75 14.9375" stroke="#70706E" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||||
|
<path d="M2.75 12.3594V12.3499C2.75 9.98664 4.68359 8.75 7.04688 8.75H10.1406C12.5039 8.75 14.4375 9.99609 14.4375 12.3594V12.3499M10.3555 5.3125L10.6752 8.06121M14.7812 14.9375H7.70473C7.61368 14.9375 7.52637 14.9737 7.46195 15.038L6.3091 16.1909C6.29314 16.2069 6.27418 16.2196 6.25332 16.2282C6.23245 16.2369 6.21009 16.2413 6.1875 16.2413C6.16491 16.2413 6.14255 16.2369 6.12168 16.2282C6.10082 16.2196 6.08186 16.2069 6.0659 16.1909L4.91305 15.038C4.84863 14.9737 4.76132 14.9375 4.67027 14.9375H2.40625C2.13275 14.9375 1.87044 14.8288 1.67705 14.6355C1.48365 14.4421 1.375 14.1798 1.375 13.9062C1.375 13.6327 1.48365 13.3704 1.67705 13.177C1.87044 12.9836 2.13275 12.875 2.40625 12.875H14.7812C15.0548 12.875 15.3171 12.9836 15.5105 13.177C15.7039 13.3704 15.8125 13.6327 15.8125 13.9062C15.8125 14.1798 15.7039 14.4421 15.5105 14.6355C15.3171 14.8288 15.0548 14.9375 14.7812 14.9375Z" stroke="#70706E" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||||
|
<path d="M11 21.125H16.986C17.3329 21.125 17.6669 20.9939 17.9212 20.7579C18.1755 20.522 18.3312 20.1986 18.3571 19.8527L19.8945 5.3125" stroke="#70706E" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||||
|
<path d="M15.8125 5.3125L16.5 2.5625L18.5195 1.875" stroke="#70706E" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M9.625 5.3125H20.625" stroke="#70706E" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.8 KiB |
|
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="25" height="25" viewBox="0 0 25 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M10.0068 4.25H5.50684C5.10901 4.25 4.72748 4.40804 4.44618 4.68934C4.16487 4.97064 4.00684 5.35218 4.00684 5.75V10.25C4.00684 10.6478 4.16487 11.0294 4.44618 11.3107C4.72748 11.592 5.10901 11.75 5.50684 11.75H10.0068C10.4047 11.75 10.7862 11.592 11.0675 11.3107C11.3488 11.0294 11.5068 10.6478 11.5068 10.25V5.75C11.5068 5.35218 11.3488 4.97064 11.0675 4.68934C10.7862 4.40804 10.4047 4.25 10.0068 4.25ZM10.0068 10.25H5.50684V5.75H10.0068V10.25ZM10.0068 13.25H5.50684C5.10901 13.25 4.72748 13.408 4.44618 13.6893C4.16487 13.9706 4.00684 14.3522 4.00684 14.75V19.25C4.00684 19.6478 4.16487 20.0294 4.44618 20.3107C4.72748 20.592 5.10901 20.75 5.50684 20.75H10.0068C10.4047 20.75 10.7862 20.592 11.0675 20.3107C11.3488 20.0294 11.5068 19.6478 11.5068 19.25V14.75C11.5068 14.3522 11.3488 13.9706 11.0675 13.6893C10.7862 13.408 10.4047 13.25 10.0068 13.25ZM10.0068 19.25H5.50684V14.75H10.0068V19.25ZM19.0068 4.25H14.5068C14.109 4.25 13.7275 4.40804 13.4462 4.68934C13.1649 4.97064 13.0068 5.35218 13.0068 5.75V10.25C13.0068 10.6478 13.1649 11.0294 13.4462 11.3107C13.7275 11.592 14.109 11.75 14.5068 11.75H19.0068C19.4047 11.75 19.7862 11.592 20.0675 11.3107C20.3488 11.0294 20.5068 10.6478 20.5068 10.25V5.75C20.5068 5.35218 20.3488 4.97064 20.0675 4.68934C19.7862 4.40804 19.4047 4.25 19.0068 4.25ZM19.0068 10.25H14.5068V5.75H19.0068V10.25ZM13.0068 17V14C13.0068 13.8011 13.0859 13.6103 13.2265 13.4697C13.3672 13.329 13.5579 13.25 13.7568 13.25C13.9557 13.25 14.1465 13.329 14.2872 13.4697C14.4278 13.6103 14.5068 13.8011 14.5068 14V17C14.5068 17.1989 14.4278 17.3897 14.2872 17.5303C14.1465 17.671 13.9557 17.75 13.7568 17.75C13.5579 17.75 13.3672 17.671 13.2265 17.5303C13.0859 17.3897 13.0068 17.1989 13.0068 17ZM20.5068 15.5C20.5068 15.6989 20.4278 15.8897 20.2872 16.0303C20.1465 16.171 19.9557 16.25 19.7568 16.25H17.5068V20C17.5068 20.1989 17.4278 20.3897 17.2872 20.5303C17.1465 20.671 16.9557 20.75 16.7568 20.75H13.7568C13.5579 20.75 13.3672 20.671 13.2265 20.5303C13.0859 20.3897 13.0068 20.1989 13.0068 20C13.0068 19.8011 13.0859 19.6103 13.2265 19.4697C13.3672 19.329 13.5579 19.25 13.7568 19.25H16.0068V14C16.0068 13.8011 16.0859 13.6103 16.2265 13.4697C16.3672 13.329 16.5579 13.25 16.7568 13.25C16.9557 13.25 17.1465 13.329 17.2872 13.4697C17.4278 13.6103 17.5068 13.8011 17.5068 14V14.75H19.7568C19.9557 14.75 20.1465 14.829 20.2872 14.9697C20.4278 15.1103 20.5068 15.3011 20.5068 15.5ZM20.5068 18.5V20C20.5068 20.1989 20.4278 20.3897 20.2872 20.5303C20.1465 20.671 19.9557 20.75 19.7568 20.75C19.5579 20.75 19.3672 20.671 19.2265 20.5303C19.0859 20.3897 19.0068 20.1989 19.0068 20V18.5C19.0068 18.3011 19.0859 18.1103 19.2265 17.9697C19.3672 17.829 19.5579 17.75 19.7568 17.75C19.9557 17.75 20.1465 17.829 20.2872 17.9697C20.4278 18.1103 20.5068 18.3011 20.5068 18.5Z" fill="#808080"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.8 KiB |
|
|
@ -45,5 +45,9 @@
|
||||||
<true/>
|
<true/>
|
||||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>NSCameraUsageDescription</key>
|
||||||
|
<string>This app needs access to camera to scan QR codes</string>
|
||||||
|
<key>NSPhotoLibraryUsageDescription</key>
|
||||||
|
<string>This app needs access to photo library to select QR code images</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
||||||
|
|
@ -127,9 +127,29 @@ class $AssetsIconsGen {
|
||||||
/// File path: assets/icons/game 2.svg
|
/// File path: assets/icons/game 2.svg
|
||||||
SvgGenImage get game2 => const SvgGenImage('assets/icons/game 2.svg');
|
SvgGenImage get game2 => const SvgGenImage('assets/icons/game 2.svg');
|
||||||
|
|
||||||
|
/// File path: assets/icons/game-icons_winter-gloves.svg
|
||||||
|
SvgGenImage get gameIconsWinterGloves =>
|
||||||
|
const SvgGenImage('assets/icons/game-icons_winter-gloves.svg');
|
||||||
|
|
||||||
/// File path: assets/icons/game.svg
|
/// File path: assets/icons/game.svg
|
||||||
SvgGenImage get game => const SvgGenImage('assets/icons/game.svg');
|
SvgGenImage get game => const SvgGenImage('assets/icons/game.svg');
|
||||||
|
|
||||||
|
/// File path: assets/icons/girl_clothes.svg
|
||||||
|
SvgGenImage get girlClothes =>
|
||||||
|
const SvgGenImage('assets/icons/girl_clothes.svg');
|
||||||
|
|
||||||
|
/// File path: assets/icons/healthicons_fruits-outline.svg
|
||||||
|
SvgGenImage get healthiconsFruitsOutline =>
|
||||||
|
const SvgGenImage('assets/icons/healthicons_fruits-outline.svg');
|
||||||
|
|
||||||
|
/// File path: assets/icons/hugeicons_baby-boy-dress.svg
|
||||||
|
SvgGenImage get hugeiconsBabyBoyDress =>
|
||||||
|
const SvgGenImage('assets/icons/hugeicons_baby-boy-dress.svg');
|
||||||
|
|
||||||
|
/// File path: assets/icons/hugeicons_cheese-cake-01.svg
|
||||||
|
SvgGenImage get hugeiconsCheeseCake01 =>
|
||||||
|
const SvgGenImage('assets/icons/hugeicons_cheese-cake-01.svg');
|
||||||
|
|
||||||
/// File path: assets/icons/ic_round-local-offer.svg
|
/// File path: assets/icons/ic_round-local-offer.svg
|
||||||
SvgGenImage get icRoundLocalOffer =>
|
SvgGenImage get icRoundLocalOffer =>
|
||||||
const SvgGenImage('assets/icons/ic_round-local-offer.svg');
|
const SvgGenImage('assets/icons/ic_round-local-offer.svg');
|
||||||
|
|
@ -137,6 +157,10 @@ class $AssetsIconsGen {
|
||||||
/// File path: assets/icons/infoPic.svg
|
/// File path: assets/icons/infoPic.svg
|
||||||
SvgGenImage get infoPic => const SvgGenImage('assets/icons/infoPic.svg');
|
SvgGenImage get infoPic => const SvgGenImage('assets/icons/infoPic.svg');
|
||||||
|
|
||||||
|
/// File path: assets/icons/ion_fast-food-outline.svg
|
||||||
|
SvgGenImage get ionFastFoodOutline =>
|
||||||
|
const SvgGenImage('assets/icons/ion_fast-food-outline.svg');
|
||||||
|
|
||||||
/// File path: assets/icons/like.svg
|
/// File path: assets/icons/like.svg
|
||||||
SvgGenImage get like => const SvgGenImage('assets/icons/like.svg');
|
SvgGenImage get like => const SvgGenImage('assets/icons/like.svg');
|
||||||
|
|
||||||
|
|
@ -197,6 +221,9 @@ class $AssetsIconsGen {
|
||||||
/// File path: assets/icons/ph_cheese.svg
|
/// File path: assets/icons/ph_cheese.svg
|
||||||
SvgGenImage get phCheese => const SvgGenImage('assets/icons/ph_cheese.svg');
|
SvgGenImage get phCheese => const SvgGenImage('assets/icons/ph_cheese.svg');
|
||||||
|
|
||||||
|
/// File path: assets/icons/ph_qr-code.svg
|
||||||
|
SvgGenImage get phQrCode => const SvgGenImage('assets/icons/ph_qr-code.svg');
|
||||||
|
|
||||||
/// File path: assets/icons/pick up off.svg
|
/// File path: assets/icons/pick up off.svg
|
||||||
SvgGenImage get pickUpOff =>
|
SvgGenImage get pickUpOff =>
|
||||||
const SvgGenImage('assets/icons/pick up off.svg');
|
const SvgGenImage('assets/icons/pick up off.svg');
|
||||||
|
|
@ -321,9 +348,15 @@ class $AssetsIconsGen {
|
||||||
favorite,
|
favorite,
|
||||||
fluentColorLocationRipple16,
|
fluentColorLocationRipple16,
|
||||||
game2,
|
game2,
|
||||||
|
gameIconsWinterGloves,
|
||||||
game,
|
game,
|
||||||
|
girlClothes,
|
||||||
|
healthiconsFruitsOutline,
|
||||||
|
hugeiconsBabyBoyDress,
|
||||||
|
hugeiconsCheeseCake01,
|
||||||
icRoundLocalOffer,
|
icRoundLocalOffer,
|
||||||
infoPic,
|
infoPic,
|
||||||
|
ionFastFoodOutline,
|
||||||
like,
|
like,
|
||||||
list,
|
list,
|
||||||
location,
|
location,
|
||||||
|
|
@ -341,6 +374,7 @@ class $AssetsIconsGen {
|
||||||
next,
|
next,
|
||||||
notificationBing,
|
notificationBing,
|
||||||
phCheese,
|
phCheese,
|
||||||
|
phQrCode,
|
||||||
pickUpOff,
|
pickUpOff,
|
||||||
pickupOn,
|
pickupOn,
|
||||||
profile2,
|
profile2,
|
||||||
|
|
|
||||||
|
|
@ -23,4 +23,5 @@ class LightAppColors{
|
||||||
static const offerCardDetail = Color.fromARGB(255, 73, 69, 79);
|
static const offerCardDetail = Color.fromARGB(255, 73, 69, 79);
|
||||||
static const divider = Color.fromARGB(255, 189, 189, 188);
|
static const divider = Color.fromARGB(255, 189, 189, 188);
|
||||||
static const textPrice = Color.fromARGB(255, 85, 84, 81);
|
static const textPrice = Color.fromARGB(255, 85, 84, 81);
|
||||||
|
static const deliverySelectedButton = Color.fromARGB(255, 237, 247, 238);
|
||||||
}
|
}
|
||||||
|
|
@ -33,11 +33,12 @@ class _DiscoverState extends State<Discover> with TickerProviderStateMixin {
|
||||||
|
|
||||||
final List<String> categoryIcons = [
|
final List<String> categoryIcons = [
|
||||||
Assets.icons.stashStarsLight.path,
|
Assets.icons.stashStarsLight.path,
|
||||||
Assets.icons.shoppingCart.path,
|
Assets.icons.hugeiconsBabyBoyDress.path,
|
||||||
Assets.icons.elementEqual.path,
|
Assets.icons.girlClothes.path,
|
||||||
Assets.icons.shop.path,
|
Assets.icons.gameIconsWinterGloves.path,
|
||||||
Assets.icons.game.path,
|
Assets.icons.hugeiconsCheeseCake01.path,
|
||||||
Assets.icons.receiptDiscount.path,
|
Assets.icons.ionFastFoodOutline.path,
|
||||||
|
Assets.icons.healthiconsFruitsOutline.path,
|
||||||
];
|
];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -336,7 +337,7 @@ class _DiscoverState extends State<Discover> with TickerProviderStateMixin {
|
||||||
|
|
||||||
Widget _buildCategoryIcons() {
|
Widget _buildCategoryIcons() {
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: 60,
|
height: 50,
|
||||||
child: ListView.separated(
|
child: ListView.separated(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
itemCount: categoryIcons.length,
|
itemCount: categoryIcons.length,
|
||||||
|
|
@ -351,9 +352,9 @@ class _DiscoverState extends State<Discover> with TickerProviderStateMixin {
|
||||||
: Colors.grey.shade600;
|
: Colors.grey.shade600;
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
width: 60,
|
width: 50,
|
||||||
height: 60,
|
height: 50,
|
||||||
padding: const EdgeInsets.all(16),
|
padding: const EdgeInsets.all(11),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: backgroundColor,
|
color: backgroundColor,
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
|
@ -600,7 +601,7 @@ class _DiscoverState extends State<Discover> with TickerProviderStateMixin {
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(15),
|
borderRadius: BorderRadius.circular(15),
|
||||||
image: DecorationImage(
|
image: DecorationImage(
|
||||||
image: AssetImage(Assets.images.topDealsAndStores.path),
|
image: AssetImage(Assets.images.wp1929534FastFoodWallpapers1.path),
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -861,7 +862,7 @@ class FlashSaleCard extends StatelessWidget {
|
||||||
),
|
),
|
||||||
Image.asset(
|
Image.asset(
|
||||||
imagePath,
|
imagePath,
|
||||||
height: 100,
|
height: 110,
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
),
|
),
|
||||||
|
|
@ -889,7 +890,7 @@ class FlashSaleCard extends StatelessWidget {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 6),
|
const SizedBox(height: 8),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.asset(
|
||||||
|
|
@ -905,7 +906,7 @@ class FlashSaleCard extends StatelessWidget {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 6),
|
const SizedBox(height: 8),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.asset(
|
||||||
|
|
@ -953,43 +954,67 @@ class FlashSaleCard extends StatelessWidget {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
Center(
|
Row(
|
||||||
child: SizedBox(
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
width: 150,
|
children: [
|
||||||
height: 38,
|
Container(
|
||||||
child: ElevatedButton(
|
decoration: BoxDecoration(
|
||||||
onPressed: () {},
|
borderRadius: BorderRadius.circular(25),
|
||||||
style: ElevatedButton.styleFrom(
|
border: Border.all(color: const Color.fromARGB(255, 76, 175, 80), width: 1.0),
|
||||||
elevation: 0,
|
color: Colors.transparent,
|
||||||
backgroundColor: Colors.green,
|
|
||||||
foregroundColor: Colors.white,
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(20),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
child: Center(
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(8, 4, 8, 4),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.asset(
|
||||||
Assets.icons.shoppingCart.path,
|
Assets.icons.cardPos.path,
|
||||||
color: Colors.white,
|
color: const Color.fromARGB(255, 95, 95, 95),
|
||||||
width: 20,
|
height: 17,
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
width: 5,
|
|
||||||
),
|
),
|
||||||
|
const SizedBox(width: 4),
|
||||||
const Text(
|
const Text(
|
||||||
"Reservation",
|
"Delivery",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.bold, fontSize: 15),
|
color: Color.fromARGB(255, 95, 95, 95),
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
fontSize: 12,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(width: 8),
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(25),
|
||||||
|
border: Border.all(color: const Color.fromARGB(255, 76, 175, 80), width: 1.0),
|
||||||
|
color: Colors.transparent,
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(8, 4, 8, 4),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
SvgPicture.asset(
|
||||||
|
Assets.icons.shoppingCart.path,
|
||||||
|
color: const Color.fromARGB(255, 95, 95, 95),
|
||||||
|
height: 17,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
const Text(
|
||||||
|
"Pickup",
|
||||||
|
style: TextStyle(
|
||||||
|
color: Color.fromARGB(255, 95, 95, 95),
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
fontSize: 12,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -1043,7 +1068,6 @@ class SeasonalDiscountCard extends StatelessWidget {
|
||||||
_buildDetailRow(
|
_buildDetailRow(
|
||||||
icon: Assets.icons.winter.path,
|
icon: Assets.icons.winter.path,
|
||||||
text: title,
|
text: title,
|
||||||
iconColor: const Color.fromARGB(255, 23, 107, 173),
|
|
||||||
textStyle: const TextStyle(
|
textStyle: const TextStyle(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
|
|
@ -1052,7 +1076,6 @@ class SeasonalDiscountCard extends StatelessWidget {
|
||||||
_buildDetailRow(
|
_buildDetailRow(
|
||||||
icon: Assets.icons.shop.path,
|
icon: Assets.icons.shop.path,
|
||||||
text: brand,
|
text: brand,
|
||||||
iconColor: Colors.grey.shade600,
|
|
||||||
textStyle: const TextStyle(
|
textStyle: const TextStyle(
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
|
|
@ -1061,7 +1084,6 @@ class SeasonalDiscountCard extends StatelessWidget {
|
||||||
_buildDetailRow(
|
_buildDetailRow(
|
||||||
icon: Assets.icons.icRoundLocalOffer.path,
|
icon: Assets.icons.icRoundLocalOffer.path,
|
||||||
text: discount,
|
text: discount,
|
||||||
iconColor: Colors.grey.shade600,
|
|
||||||
textStyle: const TextStyle(
|
textStyle: const TextStyle(
|
||||||
color: Colors.red,
|
color: Colors.red,
|
||||||
fontWeight: FontWeight.normal,
|
fontWeight: FontWeight.normal,
|
||||||
|
|
@ -1091,7 +1113,6 @@ class SeasonalDiscountCard extends StatelessWidget {
|
||||||
Widget _buildDetailRow({
|
Widget _buildDetailRow({
|
||||||
required String icon,
|
required String icon,
|
||||||
required String text,
|
required String text,
|
||||||
required Color iconColor,
|
|
||||||
required TextStyle textStyle,
|
required TextStyle textStyle,
|
||||||
}) {
|
}) {
|
||||||
return Row(
|
return Row(
|
||||||
|
|
@ -1101,7 +1122,6 @@ class SeasonalDiscountCard extends StatelessWidget {
|
||||||
padding: const EdgeInsets.only(top: 2.0),
|
padding: const EdgeInsets.only(top: 2.0),
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
icon,
|
icon,
|
||||||
color: iconColor,
|
|
||||||
width: 20,
|
width: 20,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,9 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:lba/gen/assets.gen.dart';
|
import 'package:lba/gen/assets.gen.dart';
|
||||||
import 'package:lba/res/colors.dart';
|
import 'package:lba/res/colors.dart';
|
||||||
|
import 'package:lba/screens/product/map_selection_screen.dart';
|
||||||
|
import 'package:lba/widgets/add_card_bottom_sheet.dart';
|
||||||
|
import 'package:lba/widgets/time_selection_bottom_sheet.dart';
|
||||||
|
|
||||||
class CheckoutPage extends StatefulWidget {
|
class CheckoutPage extends StatefulWidget {
|
||||||
const CheckoutPage({super.key});
|
const CheckoutPage({super.key});
|
||||||
|
|
@ -13,6 +16,11 @@ class CheckoutPage extends StatefulWidget {
|
||||||
class _CheckoutPageState extends State<CheckoutPage>
|
class _CheckoutPageState extends State<CheckoutPage>
|
||||||
with TickerProviderStateMixin {
|
with TickerProviderStateMixin {
|
||||||
int _selectedTabIndex = 0;
|
int _selectedTabIndex = 0;
|
||||||
|
String? _selectedAddress;
|
||||||
|
String? _selectedTime;
|
||||||
|
String? _selectedPickupTime;
|
||||||
|
int _selectedDeliveryOption = 0;
|
||||||
|
String? _cardNumber;
|
||||||
|
|
||||||
late AnimationController _deliveryController;
|
late AnimationController _deliveryController;
|
||||||
late AnimationController _pickupController;
|
late AnimationController _pickupController;
|
||||||
|
|
@ -80,6 +88,65 @@ class _CheckoutPageState extends State<CheckoutPage>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _selectAddress() async {
|
||||||
|
final result = await Navigator.push<String>(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (context) => const MapSelectionScreen()),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result != null && result.isNotEmpty) {
|
||||||
|
setState(() {
|
||||||
|
_selectedAddress = result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _selectTime() async {
|
||||||
|
final result = await showModalBottomSheet<String>(
|
||||||
|
context: context,
|
||||||
|
isScrollControlled: true,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
builder: (context) => const TimeSelectionBottomSheet(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result != null && result.isNotEmpty) {
|
||||||
|
setState(() {
|
||||||
|
_selectedTime = result;
|
||||||
|
_selectedDeliveryOption = 2;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _selectPickupTime() async {
|
||||||
|
final result = await showModalBottomSheet<String>(
|
||||||
|
context: context,
|
||||||
|
isScrollControlled: true,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
builder: (context) => const TimeSelectionBottomSheet(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result != null && result.isNotEmpty) {
|
||||||
|
setState(() {
|
||||||
|
_selectedPickupTime = result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _addCard() async {
|
||||||
|
final result = await showModalBottomSheet<String>(
|
||||||
|
context: context,
|
||||||
|
isScrollControlled: true,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
builder: (context) => const AddCardBottomSheet(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result != null && result.isNotEmpty) {
|
||||||
|
setState(() {
|
||||||
|
_cardNumber = result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
|
@ -97,8 +164,7 @@ class _CheckoutPageState extends State<CheckoutPage>
|
||||||
opacity: animation,
|
opacity: animation,
|
||||||
child: SlideTransition(
|
child: SlideTransition(
|
||||||
position: Tween<Offset>(
|
position: Tween<Offset>(
|
||||||
begin:
|
begin: Offset(_selectedTabIndex == 0 ? 0.5 : -0.5, 0),
|
||||||
Offset(_selectedTabIndex == 0 ? 0.5 : -0.5, 0),
|
|
||||||
end: Offset.zero,
|
end: Offset.zero,
|
||||||
).animate(animation),
|
).animate(animation),
|
||||||
child: child,
|
child: child,
|
||||||
|
|
@ -116,6 +182,80 @@ class _CheckoutPageState extends State<CheckoutPage>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _deliveryTimeCards() {
|
||||||
|
bool isAsapSelected = _selectedDeliveryOption == 1;
|
||||||
|
bool isScheduleSelected = _selectedDeliveryOption == 2;
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
_clickableCard(
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
_selectedDeliveryOption = 1;
|
||||||
|
_selectedTime = null;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
isSelected: isAsapSelected,
|
||||||
|
customChild: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: const [
|
||||||
|
Text(
|
||||||
|
"ASAP",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 15,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Colors.black),
|
||||||
|
),
|
||||||
|
SizedBox(height: 4),
|
||||||
|
Text(
|
||||||
|
"Delivered directly to you",
|
||||||
|
style:
|
||||||
|
TextStyle(fontSize: 13, color: greyTextLight, height: 1.1),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
_clickableCard(
|
||||||
|
onTap: _selectTime,
|
||||||
|
isSelected: isScheduleSelected,
|
||||||
|
customChild: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
const Text("Schedule",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 15,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Colors.black)),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Text(
|
||||||
|
_selectedTime != null ? _selectedTime! : "Select a time",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
color: _selectedTime != null
|
||||||
|
? Colors.black
|
||||||
|
: greyTextLight,
|
||||||
|
height: 1.1),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SvgPicture.asset(
|
||||||
|
Assets.icons.arrowRight.path,
|
||||||
|
height: 20,
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Widget _buildDeliveryContent() {
|
Widget _buildDeliveryContent() {
|
||||||
return SingleChildScrollView(
|
return SingleChildScrollView(
|
||||||
key: const ValueKey('delivery'),
|
key: const ValueKey('delivery'),
|
||||||
|
|
@ -125,7 +265,7 @@ class _CheckoutPageState extends State<CheckoutPage>
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
_sectionHeader("Deliver to:",
|
_sectionHeader("Deliver to:",
|
||||||
trailingAction: "Select address", onAction: () {}),
|
trailingAction: "Select address", onAction: _selectAddress),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
_selectAddressRow(),
|
_selectAddressRow(),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
|
|
@ -141,8 +281,8 @@ class _CheckoutPageState extends State<CheckoutPage>
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
_clickableCard(
|
_clickableCard(
|
||||||
leading: Assets.icons.cardAdd.path,
|
leading: Assets.icons.cardAdd.path,
|
||||||
title: "Add a credit card",
|
title: _cardNumber ?? "Add a credit card",
|
||||||
onTap: () {},
|
onTap: _addCard,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 24),
|
const SizedBox(height: 24),
|
||||||
const DottedDivider(),
|
const DottedDivider(),
|
||||||
|
|
@ -174,9 +314,9 @@ class _CheckoutPageState extends State<CheckoutPage>
|
||||||
const DottedDivider(),
|
const DottedDivider(),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
_sectionHeader("Pickup time:",
|
_sectionHeader("Pickup time:",
|
||||||
trailingAction: "Select time", onAction: () {}),
|
trailingAction: "Select time", onAction: _selectPickupTime),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
_pickupTimeRow("Set a time for your Pickup"),
|
_pickupTimeRow(_selectedPickupTime ?? "Set a time for your Pickup"),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
const DottedDivider(),
|
const DottedDivider(),
|
||||||
const SizedBox(height: 15),
|
const SizedBox(height: 15),
|
||||||
|
|
@ -184,8 +324,8 @@ class _CheckoutPageState extends State<CheckoutPage>
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
_clickableCard(
|
_clickableCard(
|
||||||
leading: Assets.icons.cardAdd.path,
|
leading: Assets.icons.cardAdd.path,
|
||||||
title: "Add a credit card",
|
title: _cardNumber ?? "Add a credit card",
|
||||||
onTap: () {},
|
onTap: _addCard,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 24),
|
const SizedBox(height: 24),
|
||||||
const DottedDivider(),
|
const DottedDivider(),
|
||||||
|
|
@ -364,22 +504,28 @@ class _CheckoutPageState extends State<CheckoutPage>
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _selectAddressRow() {
|
Widget _selectAddressRow() {
|
||||||
return Row(
|
return GestureDetector(
|
||||||
children: [
|
onTap: _selectAddress,
|
||||||
SvgPicture.asset(
|
child: Row(
|
||||||
Assets.icons.location.path,
|
children: [
|
||||||
color: const Color.fromARGB(255, 85, 84, 81),
|
SvgPicture.asset(
|
||||||
),
|
Assets.icons.location.path,
|
||||||
const SizedBox(width: 10),
|
color: const Color.fromARGB(255, 85, 84, 81),
|
||||||
const Text(
|
|
||||||
"Select address",
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 15,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: greyTextMid,
|
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(width: 10),
|
||||||
],
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
_selectedAddress ?? "Select address",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 15,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: _selectedAddress == null ? greyTextMid : Colors.black,
|
||||||
|
),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -404,92 +550,42 @@ class _CheckoutPageState extends State<CheckoutPage>
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _pickupTimeRow(String time) {
|
Widget _pickupTimeRow(String time) {
|
||||||
|
bool hasSelectedTime = _selectedPickupTime != null;
|
||||||
return Text(
|
return Text(
|
||||||
time,
|
time,
|
||||||
style: const TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 15,
|
fontSize: 15,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: greyTextMid,
|
color: hasSelectedTime ? Colors.black : greyTextMid,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _deliveryTimeCards() {
|
|
||||||
return Column(
|
|
||||||
children: [
|
|
||||||
_clickableCard(
|
|
||||||
customChild: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: const [
|
|
||||||
Text(
|
|
||||||
"ASAP",
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 15,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: Colors.black),
|
|
||||||
),
|
|
||||||
SizedBox(height: 4),
|
|
||||||
Text(
|
|
||||||
"Delivered directly to you",
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 13, color: greyTextLight, height: 1.1),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
onTap: () {},
|
|
||||||
),
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
_clickableCard(
|
|
||||||
customChild: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: const [
|
|
||||||
Text("Schedule",
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 15,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: Colors.black)),
|
|
||||||
SizedBox(height: 4),
|
|
||||||
Text("Select a time",
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 13,
|
|
||||||
color: greyTextLight,
|
|
||||||
height: 1.1)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SvgPicture.asset(
|
|
||||||
Assets.icons.arrowRight.path,
|
|
||||||
height: 20,
|
|
||||||
color: Colors.black,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
onTap: () {},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _clickableCard({
|
Widget _clickableCard({
|
||||||
String? leading,
|
String? leading,
|
||||||
String? title,
|
String? title,
|
||||||
Widget? customChild,
|
Widget? customChild,
|
||||||
VoidCallback? onTap,
|
VoidCallback? onTap,
|
||||||
|
bool isSelected = false,
|
||||||
}) {
|
}) {
|
||||||
return InkWell(
|
return InkWell(
|
||||||
borderRadius: BorderRadius.circular(6),
|
borderRadius: BorderRadius.circular(15),
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
child: Container(
|
child: AnimatedContainer(
|
||||||
|
duration: const Duration(milliseconds: 300),
|
||||||
|
curve: Curves.easeInOut,
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 14),
|
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 14),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
color:
|
||||||
|
isSelected ? LightAppColors.deliverySelectedButton : Colors.white,
|
||||||
borderRadius: BorderRadius.circular(15),
|
borderRadius: BorderRadius.circular(15),
|
||||||
border: Border.all(color: LightAppColors.divider),
|
border: Border.all(
|
||||||
|
color: isSelected
|
||||||
|
? LightAppColors.confirmButton
|
||||||
|
: LightAppColors.divider,
|
||||||
|
width: isSelected ? 1.5 : 1.0,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: customChild ??
|
child: customChild ??
|
||||||
Row(
|
Row(
|
||||||
|
|
@ -507,8 +603,7 @@ class _CheckoutPageState extends State<CheckoutPage>
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Icon(Icons.arrow_forward_ios,
|
const Icon(Icons.arrow_forward_ios, size: 16),
|
||||||
size: 16, color: greyTextLight),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,207 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_map/flutter_map.dart';
|
||||||
|
// import 'package:geocoding/geocoding.dart';
|
||||||
|
import 'package:geolocator/geolocator.dart';
|
||||||
|
import 'package:latlong2/latlong.dart';
|
||||||
|
import 'package:lba/res/colors.dart';
|
||||||
|
|
||||||
|
class MapSelectionScreen extends StatefulWidget {
|
||||||
|
const MapSelectionScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<MapSelectionScreen> createState() => _MapSelectionScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MapSelectionScreenState extends State<MapSelectionScreen> {
|
||||||
|
final MapController _mapController = MapController();
|
||||||
|
LatLng _currentCenter = const LatLng(25.1972, 55.2744);
|
||||||
|
String _addressText = "Loading address...";
|
||||||
|
bool _isLoading = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_getAddressFromLatLng(_currentCenter);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _getAddressFromLatLng(LatLng latLng) async {
|
||||||
|
try {
|
||||||
|
// List<Placemark> placemarks =`
|
||||||
|
// await placemarkFromCoordinates(latLng.latitude, latLng.longitude);
|
||||||
|
// if (placemarks.isNotEmpty) {
|
||||||
|
// final p = placemarks.first;
|
||||||
|
// setState(() {
|
||||||
|
// _addressText =
|
||||||
|
// "${p.street ?? ''}, ${p.locality ?? ''}, ${p.country ?? ''}".trim().replaceAll(RegExp(r'^,|, $'), '');
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
setState(() {
|
||||||
|
_addressText = "Lat: ${latLng.latitude.toStringAsFixed(4)}, Lng: ${latLng.longitude.toStringAsFixed(4)}";
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
setState(() {
|
||||||
|
_addressText = "Could not get address";
|
||||||
|
});
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _goToCurrentUserLocation() async {
|
||||||
|
setState(() => _isLoading = true);
|
||||||
|
|
||||||
|
bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
|
||||||
|
if (!serviceEnabled) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
|
||||||
|
content: Text('Location services are disabled. Please enable them in settings.')));
|
||||||
|
await Geolocator.openLocationSettings();
|
||||||
|
setState(() => _isLoading = false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocationPermission permission = await Geolocator.checkPermission();
|
||||||
|
if (permission == LocationPermission.denied) {
|
||||||
|
permission = await Geolocator.requestPermission();
|
||||||
|
if (permission == LocationPermission.denied) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(content: Text('Location permissions are denied.')));
|
||||||
|
setState(() => _isLoading = false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (permission == LocationPermission.deniedForever) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
|
||||||
|
content: Text(
|
||||||
|
'Location permissions are permanently denied, we cannot request permissions.')));
|
||||||
|
setState(() => _isLoading = false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Position position = await Geolocator.getCurrentPosition(
|
||||||
|
desiredAccuracy: LocationAccuracy.high);
|
||||||
|
final userLatLng = LatLng(position.latitude, position.longitude);
|
||||||
|
_mapController.move(userLatLng, 15.0);
|
||||||
|
await _getAddressFromLatLng(userLatLng);
|
||||||
|
} catch (e) {
|
||||||
|
print("Error getting current location: $e");
|
||||||
|
} finally {
|
||||||
|
setState(() => _isLoading = false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('Select Delivery Address', style: TextStyle(color: Colors.black, fontSize: 18)),
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
iconTheme: const IconThemeData(color: Colors.black),
|
||||||
|
elevation: 1,
|
||||||
|
),
|
||||||
|
body: Stack(
|
||||||
|
children: [
|
||||||
|
FlutterMap(
|
||||||
|
mapController: _mapController,
|
||||||
|
options: MapOptions(
|
||||||
|
initialCenter: _currentCenter,
|
||||||
|
initialZoom: 14.0,
|
||||||
|
onPositionChanged: (position, hasGesture) {
|
||||||
|
if (hasGesture && position.center != null) {
|
||||||
|
_currentCenter = position.center!;
|
||||||
|
_getAddressFromLatLng(_currentCenter);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
TileLayer(
|
||||||
|
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||||
|
userAgentPackageName: 'com.example.app',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const Center(
|
||||||
|
child: Icon(
|
||||||
|
Icons.location_pin,
|
||||||
|
color: Colors.red,
|
||||||
|
size: 50,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
top: 16,
|
||||||
|
right: 16,
|
||||||
|
child: FloatingActionButton(
|
||||||
|
onPressed: _goToCurrentUserLocation,
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
child: _isLoading
|
||||||
|
? const CircularProgressIndicator()
|
||||||
|
: const Icon(Icons.my_location, color: LightAppColors.primary),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.black26,
|
||||||
|
blurRadius: 10,
|
||||||
|
offset: Offset(0, -2),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
const Text(
|
||||||
|
'Selected Address:',
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
_addressText,
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 50,
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context, _addressText);
|
||||||
|
},
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: LightAppColors.offerTimer,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: const Text(
|
||||||
|
'Confirm Address',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -21,8 +21,8 @@ class _ProductdetailState extends State<Productdetail>
|
||||||
final List<String> imageList = [
|
final List<String> imageList = [
|
||||||
Assets.images.media.path,
|
Assets.images.media.path,
|
||||||
Assets.images.topDealsAndStores.path,
|
Assets.images.topDealsAndStores.path,
|
||||||
|
Assets.images.wp1929534FastFoodWallpapers1.path,
|
||||||
Assets.images.image.path,
|
Assets.images.image.path,
|
||||||
Assets.images.topDealsAndStores.path,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
late AnimationController _controller;
|
late AnimationController _controller;
|
||||||
|
|
@ -139,8 +139,7 @@ class _ProductdetailState extends State<Productdetail>
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
child: ColorFiltered(
|
child: ColorFiltered(
|
||||||
colorFilter:
|
colorFilter:
|
||||||
selectedIndex == 1 &&
|
!isSelected
|
||||||
isSelected == false
|
|
||||||
? ColorFilter.matrix(<double>[
|
? ColorFilter.matrix(<double>[
|
||||||
0.2126,
|
0.2126,
|
||||||
0.7152,
|
0.7152,
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ class _ShopState extends State<Shop> with TickerProviderStateMixin {
|
||||||
|
|
||||||
final List<Map<String, String>> similarBusinesses = [
|
final List<Map<String, String>> similarBusinesses = [
|
||||||
{
|
{
|
||||||
"imagePath": Assets.images.image.path,
|
"imagePath": Assets.images.wp1929534FastFoodWallpapers1.path,
|
||||||
"name": "The Odd Piece",
|
"name": "The Odd Piece",
|
||||||
"location": "Al Quoz 1",
|
"location": "Al Quoz 1",
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,451 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mobile_scanner/mobile_scanner.dart';
|
||||||
|
import 'package:image_picker/image_picker.dart';
|
||||||
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
import 'package:lba/res/colors.dart';
|
||||||
|
|
||||||
|
class QRScannerPage extends StatefulWidget {
|
||||||
|
const QRScannerPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<QRScannerPage> createState() => _QRScannerPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _QRScannerPageState extends State<QRScannerPage> {
|
||||||
|
MobileScannerController cameraController = MobileScannerController();
|
||||||
|
bool _isFlashOn = false;
|
||||||
|
bool _isProcessing = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
cameraController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _toggleFlash() {
|
||||||
|
setState(() {
|
||||||
|
_isFlashOn = !_isFlashOn;
|
||||||
|
});
|
||||||
|
cameraController.toggleTorch();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> _requestStoragePermission() async {
|
||||||
|
final status = await Permission.photos.status;
|
||||||
|
|
||||||
|
if (status.isGranted) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status.isDenied) {
|
||||||
|
final result = await Permission.photos.request();
|
||||||
|
return result.isGranted;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status.isPermanentlyDenied) {
|
||||||
|
_showPermissionDeniedDialog();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showPermissionDeniedDialog() {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
title: const Text('Permission Required'),
|
||||||
|
content: const Text(
|
||||||
|
'This app needs access to your photos to select QR code images. Please enable the permission in Settings.',
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
child: const Text('Cancel'),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
openAppSettings();
|
||||||
|
},
|
||||||
|
child: const Text('Open Settings'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _pickImageFromGallery() async {
|
||||||
|
// چک کردن و گرفتن permission
|
||||||
|
final hasPermission = await _requestStoragePermission();
|
||||||
|
if (!hasPermission) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
final ImagePicker picker = ImagePicker();
|
||||||
|
final XFile? image = await picker.pickImage(
|
||||||
|
source: ImageSource.gallery,
|
||||||
|
maxWidth: 1024,
|
||||||
|
maxHeight: 1024,
|
||||||
|
imageQuality: 85,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (image != null) {
|
||||||
|
// نمایش اطلاعات فایل انتخاب شده
|
||||||
|
final fileName = image.name;
|
||||||
|
final fileSize = await image.length();
|
||||||
|
final fileSizeKB = (fileSize / 1024).toStringAsFixed(1);
|
||||||
|
|
||||||
|
_handleScanResult('Image selected:\nFile: $fileName\nSize: ${fileSizeKB}KB\nPath: ${image.path}');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text('Error selecting image: $e'),
|
||||||
|
backgroundColor: Colors.red,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: Colors.black,
|
||||||
|
body: Stack(
|
||||||
|
children: [
|
||||||
|
// Camera scanner
|
||||||
|
MobileScanner(
|
||||||
|
controller: cameraController,
|
||||||
|
onDetect: (capture) {
|
||||||
|
if (_isProcessing) return;
|
||||||
|
|
||||||
|
final List<Barcode> barcodes = capture.barcodes;
|
||||||
|
if (barcodes.isNotEmpty) {
|
||||||
|
final String code = barcodes.first.rawValue ?? '';
|
||||||
|
if (code.isNotEmpty) {
|
||||||
|
setState(() {
|
||||||
|
_isProcessing = true;
|
||||||
|
});
|
||||||
|
_handleScanResult(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
errorBuilder: (context, error, child) {
|
||||||
|
return Container(
|
||||||
|
width: double.infinity,
|
||||||
|
height: double.infinity,
|
||||||
|
color: Colors.black87,
|
||||||
|
child: Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
const Icon(
|
||||||
|
Icons.camera_alt_outlined,
|
||||||
|
color: Colors.white54,
|
||||||
|
size: 64,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
const Text(
|
||||||
|
'Camera Error',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
'Please check camera permissions',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Colors.white54,
|
||||||
|
fontSize: 14,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
|
// Top bar
|
||||||
|
SafeArea(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.arrow_back,
|
||||||
|
color: Colors.white,
|
||||||
|
size: 28,
|
||||||
|
),
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
),
|
||||||
|
const Text(
|
||||||
|
'Scan QR Code',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: Icon(
|
||||||
|
_isFlashOn ? Icons.flash_on : Icons.flash_off,
|
||||||
|
color: Colors.white,
|
||||||
|
size: 28,
|
||||||
|
),
|
||||||
|
onPressed: _toggleFlash,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// QR Scanner overlay
|
||||||
|
Center(
|
||||||
|
child: SizedBox(
|
||||||
|
width: 250,
|
||||||
|
height: 250,
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
// Scanner frame
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(
|
||||||
|
color: Colors.white,
|
||||||
|
width: 2,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Corner decorations
|
||||||
|
Positioned(
|
||||||
|
top: -2,
|
||||||
|
left: -2,
|
||||||
|
child: Container(
|
||||||
|
width: 30,
|
||||||
|
height: 30,
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
border: Border(
|
||||||
|
top: BorderSide(color: LightAppColors.primary, width: 4),
|
||||||
|
left: BorderSide(color: LightAppColors.primary, width: 4),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
top: -2,
|
||||||
|
right: -2,
|
||||||
|
child: Container(
|
||||||
|
width: 30,
|
||||||
|
height: 30,
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
border: Border(
|
||||||
|
top: BorderSide(color: LightAppColors.primary, width: 4),
|
||||||
|
right: BorderSide(color: LightAppColors.primary, width: 4),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
bottom: -2,
|
||||||
|
left: -2,
|
||||||
|
child: Container(
|
||||||
|
width: 30,
|
||||||
|
height: 30,
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
border: Border(
|
||||||
|
bottom: BorderSide(color: LightAppColors.primary, width: 4),
|
||||||
|
left: BorderSide(color: LightAppColors.primary, width: 4),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
bottom: -2,
|
||||||
|
right: -2,
|
||||||
|
child: Container(
|
||||||
|
width: 30,
|
||||||
|
height: 30,
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
border: Border(
|
||||||
|
bottom: BorderSide(color: LightAppColors.primary, width: 4),
|
||||||
|
right: BorderSide(color: LightAppColors.primary, width: 4),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Bottom instructions
|
||||||
|
Positioned(
|
||||||
|
bottom: 120,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
child: const Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 32.0),
|
||||||
|
child: Text(
|
||||||
|
'Position the QR code within the frame to scan',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Bottom buttons
|
||||||
|
Positioned(
|
||||||
|
bottom: 50,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: [
|
||||||
|
// Gallery button
|
||||||
|
Container(
|
||||||
|
width: 60,
|
||||||
|
height: 60,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white.withOpacity(0.2),
|
||||||
|
borderRadius: BorderRadius.circular(30),
|
||||||
|
),
|
||||||
|
child: IconButton(
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.photo_library,
|
||||||
|
color: Colors.white,
|
||||||
|
size: 28,
|
||||||
|
),
|
||||||
|
onPressed: _pickImageFromGallery,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
Container(
|
||||||
|
width: 60,
|
||||||
|
height: 60,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white.withOpacity(0.2),
|
||||||
|
borderRadius: BorderRadius.circular(30),
|
||||||
|
),
|
||||||
|
child: IconButton(
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.keyboard,
|
||||||
|
color: Colors.white,
|
||||||
|
size: 28,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
_showManualInputDialog();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showManualInputDialog() {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
final TextEditingController controller = TextEditingController();
|
||||||
|
return AlertDialog(
|
||||||
|
title: const Text('Enter Code Manually'),
|
||||||
|
content: TextField(
|
||||||
|
controller: controller,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
hintText: 'Enter QR code or barcode',
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
child: const Text('Cancel'),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
if (controller.text.isNotEmpty) {
|
||||||
|
Navigator.pop(context);
|
||||||
|
_handleScanResult(controller.text);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: const Text('Submit'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _handleScanResult(String result) {
|
||||||
|
// Pause camera
|
||||||
|
cameraController.stop();
|
||||||
|
|
||||||
|
// Handle the scanned result
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
barrierDismissible: false,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
title: const Text('QR Code Scanned!'),
|
||||||
|
content: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
const Text('Scanned content:', style: TextStyle(fontWeight: FontWeight.bold)),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.grey[100],
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: SelectableText(
|
||||||
|
result,
|
||||||
|
style: const TextStyle(fontSize: 14),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
setState(() {
|
||||||
|
_isProcessing = false;
|
||||||
|
});
|
||||||
|
cameraController.start();
|
||||||
|
},
|
||||||
|
child: const Text('Scan Again'),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
child: const Text('Done'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,262 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:lba/res/colors.dart';
|
||||||
|
import 'package:lba/widgets/button.dart';
|
||||||
|
|
||||||
|
class AddCardBottomSheet extends StatefulWidget {
|
||||||
|
const AddCardBottomSheet({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<AddCardBottomSheet> createState() => _AddCardBottomSheetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AddCardBottomSheetState extends State<AddCardBottomSheet> {
|
||||||
|
final TextEditingController _cardNumberController = TextEditingController();
|
||||||
|
final TextEditingController _expiryDateController = TextEditingController();
|
||||||
|
|
||||||
|
bool _isCardNumberValid = false;
|
||||||
|
bool _isExpiryDateValid = false;
|
||||||
|
final FocusNode _cardNumberFocus = FocusNode();
|
||||||
|
final FocusNode _expiryDateFocus = FocusNode();
|
||||||
|
Color _borderColor = Colors.grey.shade400;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_cardNumberController.addListener(_validateCardNumber);
|
||||||
|
_expiryDateController.addListener(_validateExpiryDate);
|
||||||
|
|
||||||
|
// Change border color on focus
|
||||||
|
_cardNumberFocus.addListener(() {
|
||||||
|
setState(() {
|
||||||
|
_borderColor = _cardNumberFocus.hasFocus || _expiryDateFocus.hasFocus
|
||||||
|
? Theme.of(context).primaryColor
|
||||||
|
: Colors.grey.shade400;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
_expiryDateFocus.addListener(() {
|
||||||
|
setState(() {
|
||||||
|
_borderColor = _cardNumberFocus.hasFocus || _expiryDateFocus.hasFocus
|
||||||
|
? Theme.of(context).primaryColor
|
||||||
|
: Colors.grey.shade400;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_cardNumberController.removeListener(_validateCardNumber);
|
||||||
|
_expiryDateController.removeListener(_validateExpiryDate);
|
||||||
|
_cardNumberController.dispose();
|
||||||
|
_expiryDateController.dispose();
|
||||||
|
_cardNumberFocus.dispose();
|
||||||
|
_expiryDateFocus.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _validateCardNumber() {
|
||||||
|
final text = _cardNumberController.text.replaceAll('-', '');
|
||||||
|
setState(() {
|
||||||
|
_isCardNumberValid = text.length == 16;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _validateExpiryDate() {
|
||||||
|
final text = _expiryDateController.text;
|
||||||
|
if (text.length == 5) {
|
||||||
|
final parts = text.split('/');
|
||||||
|
if (parts.length == 2) {
|
||||||
|
final month = int.tryParse(parts[0]);
|
||||||
|
final year = int.tryParse(parts[1]);
|
||||||
|
if (month != null && year != null) {
|
||||||
|
final now = DateTime.now();
|
||||||
|
final currentYear = now.year % 100;
|
||||||
|
final currentMonth = now.month;
|
||||||
|
if (month >= 1 &&
|
||||||
|
month <= 12 &&
|
||||||
|
(year > currentYear ||
|
||||||
|
(year == currentYear && month >= currentMonth))) {
|
||||||
|
setState(() {
|
||||||
|
_isExpiryDateValid = true;
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setState(() {
|
||||||
|
_isExpiryDateValid = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get _isFormValid => _isCardNumberValid && _isExpiryDateValid;
|
||||||
|
|
||||||
|
void _addCard() {
|
||||||
|
if (_isFormValid) {
|
||||||
|
Navigator.pop(context, _cardNumberController.text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SingleChildScrollView(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
bottom: MediaQuery.of(context).viewInsets.bottom,
|
||||||
|
),
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.all(24.0),
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.vertical(top: Radius.circular(20.0)),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
const Text(
|
||||||
|
'Add card',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.black87,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
const Divider(),
|
||||||
|
const SizedBox(height: 24),
|
||||||
|
AnimatedContainer(
|
||||||
|
duration: const Duration(milliseconds: 200),
|
||||||
|
height: 55,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(color: _borderColor, width: 1.5),
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 12.0),
|
||||||
|
child: Icon(Icons.credit_card, color: Colors.grey),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: TextFormField(
|
||||||
|
controller: _cardNumberController,
|
||||||
|
focusNode: _cardNumberFocus,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
inputFormatters: [
|
||||||
|
FilteringTextInputFormatter.digitsOnly,
|
||||||
|
LengthLimitingTextInputFormatter(16),
|
||||||
|
_CardNumberInputFormatter(),
|
||||||
|
],
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
hintText: '1234-5678-1234-5678',
|
||||||
|
border: InputBorder.none,
|
||||||
|
focusedBorder: InputBorder.none,
|
||||||
|
enabledBorder: InputBorder.none,
|
||||||
|
errorBorder: InputBorder.none,
|
||||||
|
disabledBorder: InputBorder.none,
|
||||||
|
contentPadding: EdgeInsets.symmetric(vertical: 15),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 80,
|
||||||
|
child: TextFormField(
|
||||||
|
controller: _expiryDateController,
|
||||||
|
focusNode: _expiryDateFocus,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
inputFormatters: [
|
||||||
|
FilteringTextInputFormatter.digitsOnly,
|
||||||
|
LengthLimitingTextInputFormatter(4),
|
||||||
|
_ExpiryDateInputFormatter(),
|
||||||
|
],
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
hintText: 'MM/YY',
|
||||||
|
border: InputBorder.none,
|
||||||
|
focusedBorder: InputBorder.none,
|
||||||
|
enabledBorder: InputBorder.none,
|
||||||
|
errorBorder: InputBorder.none,
|
||||||
|
disabledBorder: InputBorder.none,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 32),
|
||||||
|
SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 50,
|
||||||
|
child: Button(
|
||||||
|
text: 'Add card',
|
||||||
|
onPressed: _isFormValid ? _addCard : () {},
|
||||||
|
color: _isFormValid
|
||||||
|
? const Color(0xFFE53935)
|
||||||
|
: Colors.red.shade200,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CardNumberInputFormatter extends TextInputFormatter {
|
||||||
|
@override
|
||||||
|
TextEditingValue formatEditUpdate(
|
||||||
|
TextEditingValue oldValue, TextEditingValue newValue) {
|
||||||
|
var text = newValue.text;
|
||||||
|
|
||||||
|
if (newValue.selection.baseOffset == 0) {
|
||||||
|
return newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var buffer = StringBuffer();
|
||||||
|
for (int i = 0; i < text.length; i++) {
|
||||||
|
buffer.write(text[i]);
|
||||||
|
var nonZeroIndex = i + 1;
|
||||||
|
if (nonZeroIndex % 4 == 0 && nonZeroIndex != text.length) {
|
||||||
|
buffer.write('-');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var string = buffer.toString();
|
||||||
|
return newValue.copyWith(
|
||||||
|
text: string,
|
||||||
|
selection: TextSelection.collapsed(offset: string.length));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ExpiryDateInputFormatter extends TextInputFormatter {
|
||||||
|
@override
|
||||||
|
TextEditingValue formatEditUpdate(
|
||||||
|
TextEditingValue oldValue, TextEditingValue newValue) {
|
||||||
|
var newText = newValue.text;
|
||||||
|
|
||||||
|
if (newValue.selection.baseOffset == 0) {
|
||||||
|
return newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldValue.text.endsWith('/') &&
|
||||||
|
oldValue.text.length > newValue.text.length) {
|
||||||
|
newText = newText.substring(0, newText.length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
var buffer = StringBuffer();
|
||||||
|
for (int i = 0; i < newText.length; i++) {
|
||||||
|
buffer.write(newText[i]);
|
||||||
|
if (i == 1 && newText.length > 2 && !newText.contains('/')) {
|
||||||
|
buffer.write('/');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var string = buffer.toString();
|
||||||
|
return newValue.copyWith(
|
||||||
|
text: string.substring(0, string.length > 5 ? 5 : string.length),
|
||||||
|
selection: TextSelection.collapsed(
|
||||||
|
offset: string.length > 5 ? 5 : string.length,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -46,11 +46,14 @@ class CustomCard extends StatelessWidget {
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(11),
|
borderRadius: BorderRadius.circular(11),
|
||||||
),
|
),
|
||||||
child: Image.asset(
|
child: ClipRRect(
|
||||||
Assets.images.image.path,
|
borderRadius: BorderRadius.circular(11),
|
||||||
width: 80,
|
child: Image.asset(
|
||||||
height: 80,
|
Assets.images.wp1929534FastFoodWallpapers1.path,
|
||||||
fit: BoxFit.cover,
|
width: 80,
|
||||||
|
height: 80,
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(width: 8),
|
SizedBox(width: 8),
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:lba/gen/assets.gen.dart';
|
import 'package:lba/gen/assets.gen.dart';
|
||||||
|
import 'package:lba/screens/qr_scanner/qr_scanner_page.dart';
|
||||||
|
|
||||||
class SearchBarWidget extends StatelessWidget {
|
class SearchBarWidget extends StatelessWidget {
|
||||||
const SearchBarWidget({super.key});
|
const SearchBarWidget({super.key});
|
||||||
|
|
@ -26,6 +27,24 @@ class SearchBarWidget extends StatelessWidget {
|
||||||
height: 18,
|
height: 18,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
suffixIcon: Padding(
|
||||||
|
padding: const EdgeInsets.all(10.0),
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => const QRScannerPage(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
Assets.icons.phQrCode.path,
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
filled: true,
|
filled: true,
|
||||||
fillColor: const Color.fromARGB(255, 248, 248, 248),
|
fillColor: const Color.fromARGB(255, 248, 248, 248),
|
||||||
contentPadding: const EdgeInsets.symmetric(
|
contentPadding: const EdgeInsets.symmetric(
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,228 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:lba/res/colors.dart';
|
||||||
|
import 'package:lba/widgets/button.dart';
|
||||||
|
import 'dart:math' as math;
|
||||||
|
|
||||||
|
class TimeSelectionBottomSheet extends StatefulWidget {
|
||||||
|
const TimeSelectionBottomSheet({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<TimeSelectionBottomSheet> createState() =>
|
||||||
|
_TimeSelectionBottomSheetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _TimeSelectionBottomSheetState extends State<TimeSelectionBottomSheet> {
|
||||||
|
final List<String> _timeSlots = [];
|
||||||
|
String? _selectedTimeSlot;
|
||||||
|
late ScrollController _scrollController;
|
||||||
|
|
||||||
|
static const double _itemHeight = 50.0;
|
||||||
|
static const int _visibleItems = 3;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_generateTimeSlots();
|
||||||
|
|
||||||
|
final initialIndex = _timeSlots.length > 1 ? 1 : 0;
|
||||||
|
if (_timeSlots.isNotEmpty) {
|
||||||
|
_selectedTimeSlot = _timeSlots[initialIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
_scrollController =
|
||||||
|
ScrollController(initialScrollOffset: initialIndex * _itemHeight);
|
||||||
|
_scrollController.addListener(_onScroll);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onScroll() {
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_scrollController.removeListener(_onScroll);
|
||||||
|
_scrollController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _generateTimeSlots() {
|
||||||
|
final now = DateTime.now();
|
||||||
|
final endTime = DateTime(now.year, now.month, now.day, 22, 0);
|
||||||
|
DateTime startTime = DateTime(
|
||||||
|
now.year,
|
||||||
|
now.month,
|
||||||
|
now.day,
|
||||||
|
now.hour,
|
||||||
|
now.minute > 30 ? 60 : 30,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (startTime.isAfter(endTime)) return;
|
||||||
|
|
||||||
|
_timeSlots.add('');
|
||||||
|
while (startTime.isBefore(endTime)) {
|
||||||
|
final slotEnd = startTime.add(const Duration(minutes: 30));
|
||||||
|
final formattedStart = DateFormat('HH:mm').format(startTime);
|
||||||
|
final formattedEnd = DateFormat('HH:mm').format(slotEnd);
|
||||||
|
_timeSlots.add('$formattedStart - $formattedEnd');
|
||||||
|
startTime = slotEnd;
|
||||||
|
}
|
||||||
|
_timeSlots.add('');
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onScrollEnd() {
|
||||||
|
final currentOffset = _scrollController.offset;
|
||||||
|
final targetIndex = (currentOffset / _itemHeight).round();
|
||||||
|
final targetOffset = targetIndex * _itemHeight;
|
||||||
|
|
||||||
|
if ((targetOffset - currentOffset).abs() > 0.1) {
|
||||||
|
_scrollController.animateTo(
|
||||||
|
targetOffset,
|
||||||
|
duration: const Duration(milliseconds: 300),
|
||||||
|
curve: Curves.easeOut,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mounted && _timeSlots.isNotEmpty) {
|
||||||
|
final finalIndex = targetIndex.clamp(0, _timeSlots.length - 1);
|
||||||
|
final newSelection = _timeSlots[finalIndex];
|
||||||
|
|
||||||
|
if (_selectedTimeSlot != newSelection && newSelection.isNotEmpty) {
|
||||||
|
setState(() {
|
||||||
|
_selectedTimeSlot = newSelection;
|
||||||
|
});
|
||||||
|
HapticFeedback.lightImpact();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.vertical(top: Radius.circular(20.0)),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 40,
|
||||||
|
height: 4,
|
||||||
|
margin: const EdgeInsets.symmetric(vertical: 10),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.grey[300],
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 24.0),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
const Text('Select a time', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Divider(color: Colors.grey.shade300),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
'Philadelphia Honey Pecan Cream Cheese Spread, 7.5 oz Tub available from Now - 10:00 PM Today',
|
||||||
|
style: TextStyle(color: Colors.grey.shade600, fontSize: 14),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
_buildTimePicker(),
|
||||||
|
const SizedBox(height: 24),
|
||||||
|
SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 50,
|
||||||
|
child: Button(
|
||||||
|
text: 'Confirm',
|
||||||
|
onPressed: () {
|
||||||
|
if (_selectedTimeSlot != null && _selectedTimeSlot!.isNotEmpty) {
|
||||||
|
Navigator.pop(context, _selectedTimeSlot);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
color: LightAppColors.offerTimer,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildTimePicker() {
|
||||||
|
if (_timeSlots.length <= 2) {
|
||||||
|
return const Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.all(20.0),
|
||||||
|
child: Text('No available time slots for today.'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final listHeight = _itemHeight * _visibleItems;
|
||||||
|
|
||||||
|
return SizedBox(
|
||||||
|
height: listHeight,
|
||||||
|
child: Stack(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
children: [
|
||||||
|
Positioned(
|
||||||
|
top: _itemHeight,
|
||||||
|
bottom: _itemHeight,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: LightAppColors.fillOrder,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
NotificationListener<ScrollNotification>(
|
||||||
|
onNotification: (notification) {
|
||||||
|
if (notification is ScrollEndNotification) {
|
||||||
|
_onScrollEnd();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
child: ListView.builder(
|
||||||
|
controller: _scrollController,
|
||||||
|
padding: EdgeInsets.symmetric(vertical: (listHeight - _itemHeight) / 2),
|
||||||
|
itemCount: _timeSlots.length,
|
||||||
|
itemExtent: _itemHeight,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final centerOffset = _scrollController.offset;
|
||||||
|
final itemOffset = index * _itemHeight;
|
||||||
|
final distance = (itemOffset - centerOffset).abs();
|
||||||
|
|
||||||
|
final isSelected = distance < _itemHeight / 2;
|
||||||
|
final scale = math.max(1.0 - (distance / listHeight) * 0.7, 0.8);
|
||||||
|
final opacity = math.max(1.0 - (distance / listHeight) * 1.2, 0.3);
|
||||||
|
|
||||||
|
return Center(
|
||||||
|
child: Transform.scale(
|
||||||
|
scale: scale,
|
||||||
|
child: Text(
|
||||||
|
_timeSlots[index],
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18,
|
||||||
|
color: isSelected ? Colors.black : Colors.grey.shade600.withOpacity(opacity),
|
||||||
|
fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,10 +6,14 @@
|
||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <file_selector_linux/file_selector_plugin.h>
|
||||||
#include <maps_launcher/maps_launcher_plugin.h>
|
#include <maps_launcher/maps_launcher_plugin.h>
|
||||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||||
|
|
||||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||||
|
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
|
||||||
|
file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
|
||||||
g_autoptr(FlPluginRegistrar) maps_launcher_registrar =
|
g_autoptr(FlPluginRegistrar) maps_launcher_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "MapsLauncherPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "MapsLauncherPlugin");
|
||||||
maps_launcher_plugin_register_with_registrar(maps_launcher_registrar);
|
maps_launcher_plugin_register_with_registrar(maps_launcher_registrar);
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
file_selector_linux
|
||||||
maps_launcher
|
maps_launcher
|
||||||
url_launcher_linux
|
url_launcher_linux
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -5,16 +5,20 @@
|
||||||
import FlutterMacOS
|
import FlutterMacOS
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
import file_selector_macos
|
||||||
import geolocator_apple
|
import geolocator_apple
|
||||||
import location
|
import location
|
||||||
import maps_launcher
|
import maps_launcher
|
||||||
|
import mobile_scanner
|
||||||
import shared_preferences_foundation
|
import shared_preferences_foundation
|
||||||
import url_launcher_macos
|
import url_launcher_macos
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
|
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
||||||
GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin"))
|
GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin"))
|
||||||
LocationPlugin.register(with: registry.registrar(forPlugin: "LocationPlugin"))
|
LocationPlugin.register(with: registry.registrar(forPlugin: "LocationPlugin"))
|
||||||
MapsLauncherPlugin.register(with: registry.registrar(forPlugin: "MapsLauncherPlugin"))
|
MapsLauncherPlugin.register(with: registry.registrar(forPlugin: "MapsLauncherPlugin"))
|
||||||
|
MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin"))
|
||||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
170
pubspec.lock
|
|
@ -185,6 +185,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.1"
|
version: "3.0.1"
|
||||||
|
cross_file:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: cross_file
|
||||||
|
sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.3.4+2"
|
||||||
crypto:
|
crypto:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -273,6 +281,38 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.1"
|
version: "7.0.1"
|
||||||
|
file_selector_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: file_selector_linux
|
||||||
|
sha256: "54cbbd957e1156d29548c7d9b9ec0c0ebb6de0a90452198683a7d23aed617a33"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.9.3+2"
|
||||||
|
file_selector_macos:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: file_selector_macos
|
||||||
|
sha256: "19124ff4a3d8864fdc62072b6a2ef6c222d55a3404fe14893a3c02744907b60c"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.9.4+4"
|
||||||
|
file_selector_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: file_selector_platform_interface
|
||||||
|
sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.6.2"
|
||||||
|
file_selector_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: file_selector_windows
|
||||||
|
sha256: "320fcfb6f33caa90f0b58380489fc5ac05d99ee94b61aa96ec2bff0ba81d3c2b"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.9.3+4"
|
||||||
fixnum:
|
fixnum:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -326,6 +366,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.1.1"
|
version: "8.1.1"
|
||||||
|
flutter_plugin_android_lifecycle:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_plugin_android_lifecycle
|
||||||
|
sha256: "6382ce712ff69b0f719640ce957559dde459e55ecd433c767e06d139ddf16cab"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.29"
|
||||||
flutter_svg:
|
flutter_svg:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -448,6 +496,70 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.1.2"
|
version: "4.1.2"
|
||||||
|
image_picker:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: image_picker
|
||||||
|
sha256: "736eb56a911cf24d1859315ad09ddec0b66104bc41a7f8c5b96b4e2620cf5041"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.0"
|
||||||
|
image_picker_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_picker_android
|
||||||
|
sha256: e83b2b05141469c5e19d77e1dfa11096b6b1567d09065b2265d7c6904560050c
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.8.13"
|
||||||
|
image_picker_for_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_picker_for_web
|
||||||
|
sha256: "40c2a6a0da15556dc0f8e38a3246064a971a9f512386c3339b89f76db87269b6"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.0"
|
||||||
|
image_picker_ios:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_picker_ios
|
||||||
|
sha256: eb06fe30bab4c4497bad449b66448f50edcc695f1c59408e78aa3a8059eb8f0e
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.8.13"
|
||||||
|
image_picker_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_picker_linux
|
||||||
|
sha256: "1f81c5f2046b9ab724f85523e4af65be1d47b038160a8c8deed909762c308ed4"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.2"
|
||||||
|
image_picker_macos:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_picker_macos
|
||||||
|
sha256: d58cd9d67793d52beefd6585b12050af0a7663c0c2a6ece0fb110a35d6955e04
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.2"
|
||||||
|
image_picker_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_picker_platform_interface
|
||||||
|
sha256: "9f143b0dba3e459553209e20cc425c9801af48e6dfa4f01a0fcf927be3f41665"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.11.0"
|
||||||
|
image_picker_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_picker_windows
|
||||||
|
sha256: d248c86554a72b5495a31c56f060cf73a41c7ff541689327b1a7dbccc33adfae
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.2"
|
||||||
image_size_getter:
|
image_size_getter:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -624,6 +736,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
|
mobile_scanner:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: mobile_scanner
|
||||||
|
sha256: d234581c090526676fd8fab4ada92f35c6746e3fb4f05a399665d75a399fb760
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.2.3"
|
||||||
nested:
|
nested:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -680,6 +800,54 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.0"
|
version: "2.3.0"
|
||||||
|
permission_handler:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: permission_handler
|
||||||
|
sha256: "59adad729136f01ea9e35a48f5d1395e25cba6cea552249ddbe9cf950f5d7849"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "11.4.0"
|
||||||
|
permission_handler_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: permission_handler_android
|
||||||
|
sha256: d3971dcdd76182a0c198c096b5db2f0884b0d4196723d21a866fc4cdea057ebc
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "12.1.0"
|
||||||
|
permission_handler_apple:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: permission_handler_apple
|
||||||
|
sha256: f000131e755c54cf4d84a5d8bd6e4149e262cc31c5a8b1d698de1ac85fa41023
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "9.4.7"
|
||||||
|
permission_handler_html:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: permission_handler_html
|
||||||
|
sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.3+5"
|
||||||
|
permission_handler_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: permission_handler_platform_interface
|
||||||
|
sha256: eb99b295153abce5d683cac8c02e22faab63e50679b937fa1bf67d58bb282878
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.3.0"
|
||||||
|
permission_handler_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: permission_handler_windows
|
||||||
|
sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.1"
|
||||||
petitparser:
|
petitparser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -1111,4 +1279,4 @@ packages:
|
||||||
version: "3.1.3"
|
version: "3.1.3"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.7.2 <4.0.0"
|
dart: ">=3.7.2 <4.0.0"
|
||||||
flutter: ">=3.27.0"
|
flutter: ">=3.29.0"
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,10 @@ dependencies:
|
||||||
location: ^8.0.0
|
location: ^8.0.0
|
||||||
maps_launcher: ^3.0.0+1
|
maps_launcher: ^3.0.0+1
|
||||||
dots_indicator: ^4.0.1
|
dots_indicator: ^4.0.1
|
||||||
|
mobile_scanner: ^5.1.1
|
||||||
|
image_picker: ^1.1.2
|
||||||
|
permission_handler: ^11.3.1
|
||||||
|
# geocoding: ^3.0.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
|
||||||
|
|
@ -6,15 +6,21 @@
|
||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <file_selector_windows/file_selector_windows.h>
|
||||||
#include <geolocator_windows/geolocator_windows.h>
|
#include <geolocator_windows/geolocator_windows.h>
|
||||||
#include <maps_launcher/maps_launcher_plugin.h>
|
#include <maps_launcher/maps_launcher_plugin.h>
|
||||||
|
#include <permission_handler_windows/permission_handler_windows_plugin.h>
|
||||||
#include <url_launcher_windows/url_launcher_windows.h>
|
#include <url_launcher_windows/url_launcher_windows.h>
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
|
FileSelectorWindowsRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("FileSelectorWindows"));
|
||||||
GeolocatorWindowsRegisterWithRegistrar(
|
GeolocatorWindowsRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("GeolocatorWindows"));
|
registry->GetRegistrarForPlugin("GeolocatorWindows"));
|
||||||
MapsLauncherPluginRegisterWithRegistrar(
|
MapsLauncherPluginRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("MapsLauncherPlugin"));
|
registry->GetRegistrarForPlugin("MapsLauncherPlugin"));
|
||||||
|
PermissionHandlerWindowsPluginRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
|
||||||
UrlLauncherWindowsRegisterWithRegistrar(
|
UrlLauncherWindowsRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
|
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,10 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
file_selector_windows
|
||||||
geolocator_windows
|
geolocator_windows
|
||||||
maps_launcher
|
maps_launcher
|
||||||
|
permission_handler_windows
|
||||||
url_launcher_windows
|
url_launcher_windows
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||