Browse Source

add: home feature

pull/8/head
AmirrezaChegini 1 week ago
parent
commit
605ba07855
  1. 22
      assets/images/current_mission.svg
  2. 76
      assets/images/finished_mission.svg
  3. 13
      assets/images/location.svg
  4. BIN
      assets/images/map_background.png
  5. 22
      assets/images/mission.svg
  6. 5
      lib/common_ui/resources/my_assets.dart
  7. 13
      lib/core/params/home_params.dart
  8. 28
      lib/features/home/data/datasource/home_datasource.dart
  9. 13
      lib/features/home/data/model/home_model.dart
  10. 29
      lib/features/home/data/repository_impl/home_repository_impl.dart
  11. 14
      lib/features/home/domain/entity/home_entity.dart
  12. 8
      lib/features/home/domain/repository/home_repository.dart
  13. 17
      lib/features/home/domain/usecases/get_home_usecase.dart
  14. 41
      lib/features/home/presentation/bloc/home_bloc.dart
  15. 5
      lib/features/home/presentation/bloc/home_event.dart
  16. 15
      lib/features/home/presentation/bloc/home_state.dart
  17. 601
      lib/features/home/presentation/ui/home_page.dart
  18. 9
      lib/init_bindings.dart
  19. 12
      pubspec.lock
  20. 1
      pubspec.yaml

22
assets/images/current_mission.svg

@ -0,0 +1,22 @@
<svg width="84" height="94" viewBox="0 0 84 94" fill="none" xmlns="http://www.w3.org/2000/svg">
<g opacity="0.3">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.98593 33.9953L0.770142 69.7487L19.9682 88.9068L58.7534 93.392L78.6 77.3094L84.0481 31.176L4.98593 33.9953Z" fill="black" style="mix-blend-mode:multiply"/>
</g>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.82872 57.318L4.53156 22.0772L27.1671 8.42944L68.1575 13.1069L84.0477 31.1758L77.3673 66.0321L55.121 76.0277L22.8216 72.3114L5.82872 57.318Z" fill="url(#paint0_radial_36_36)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M68.1581 13.1072L63.8775 2.53496L30.2809 0.933105L27.1678 8.42978L68.1581 13.1072Z" fill="#FFE313"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M84.0483 31.1761L63.8774 2.53491L66.3421 12.9149L84.0483 31.1761Z" fill="#FFBD13"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M30.2803 0.933105L27.1671 8.42978L4.53156 22.0776L10.7579 14.1965L30.2803 0.933105Z" fill="#FFBD13"/>
<g style="mix-blend-mode:soft-light">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.53156 22.0772L23.4053 40.2102L70.9464 42.0043L84.0477 31.1758L66.3414 12.9146L27.1671 8.42944L4.53156 22.0772Z" fill="#FCCA70"/>
</g>
<path fill-rule="evenodd" clip-rule="evenodd" d="M56.3539 11.7616L73.6062 19.3224L65.6286 10.0957L56.3539 11.7616Z" fill="#FFFF18"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M28.2704 5.80273L31.643 8.94237L22.5629 11.185L28.2704 5.80273Z" fill="#FFFF18"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M63.0338 71.9912L47.0786 75.0668L55.1211 76.0279L63.0338 71.9912Z" fill="#F48600"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.4012 66.6733L30.6051 73.2089L22.8221 72.3119L16.4012 66.6733Z" fill="#F48600"/>
<defs>
<radialGradient id="paint0_radial_36_36" cx="0" cy="0" r="1" gradientTransform="matrix(45.2678 5.42067 -4.11525 33.8792 -35.2609 101.011)" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFCE1B"/>
<stop offset="1" stop-color="#FF901D"/>
</radialGradient>
</defs>
</svg>

76
assets/images/finished_mission.svg

@ -0,0 +1,76 @@
<svg width="82" height="93" viewBox="0 0 82 93" fill="none" xmlns="http://www.w3.org/2000/svg">
<g opacity="0.3">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.13747 33.4213L-0.000244141 69.1747L18.8423 88.3329L56.9092 92.8181L76.3883 76.7354L81.7355 30.6021L4.13747 33.4213Z" fill="black" style="mix-blend-mode:multiply"/>
</g>
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.96507 56.744L3.69193 21.5033L25.9083 7.85547L66.1396 12.5329L81.7356 30.6018L75.1789 65.4581L53.3445 75.4537L21.6432 71.7374L4.96507 56.744Z" fill="url(#paint0_radial_36_7)"/>
<path style="mix-blend-mode:screen" d="M22.6686 31.7387C23.0418 31.722 23.4068 31.8517 23.687 32.1004C23.9672 32.3491 24.1407 32.6975 24.1711 33.0723C24.1817 33.2579 24.1561 33.4439 24.0953 33.6195C24.0345 33.795 23.9399 33.9568 23.8168 34.0955C23.6938 34.2342 23.5446 34.347 23.3781 34.4276C23.2116 34.5082 23.0311 34.5549 22.8467 34.5651C22.6623 34.5786 22.4773 34.5553 22.3018 34.4965C22.1264 34.4378 21.9641 34.3447 21.8245 34.2226C21.6849 34.1005 21.5705 33.9519 21.4881 33.7852C21.4057 33.6186 21.3568 33.4372 21.3443 33.2514C21.3226 32.8745 21.4496 32.5041 21.6976 32.2208C21.9456 31.9376 22.2945 31.7643 22.6686 31.7387Z" fill="url(#paint1_radial_36_7)"/>
<path d="M22.3056 32.7197C22.5075 32.7188 22.7024 32.7934 22.8522 32.9288C23.0019 33.0643 23.0954 33.2508 23.1146 33.4517C23.1156 33.6536 23.0413 33.8485 22.9058 33.9982C22.7703 34.1479 22.5837 34.2415 22.3827 34.2607C22.1808 34.2616 21.9859 34.187 21.8362 34.0516C21.6864 33.9162 21.5929 33.7297 21.5737 33.5287C21.5728 33.3269 21.6471 33.132 21.7825 32.9823C21.918 32.8326 22.1046 32.739 22.3056 32.7197Z" fill="white"/>
<path style="mix-blend-mode:screen" d="M16.0068 11.923C17.0556 11.8631 18.0853 12.2205 18.8715 12.9173C19.6577 13.6141 20.1363 14.5935 20.2029 15.6419C20.2627 16.6907 19.9052 17.7206 19.2085 18.5068C18.5117 19.293 17.5325 19.7717 16.4841 19.8382C15.4353 19.8981 14.4051 19.5407 13.6189 18.8439C12.8328 18.1471 12.3542 17.1677 12.2876 16.1193C12.2277 15.0705 12.5852 14.0405 13.282 13.2544C13.9788 12.4682 14.9584 11.9896 16.0068 11.923Z" fill="url(#paint2_radial_36_7)"/>
<path d="M16.7405 14.7511C16.8895 14.74 17.039 14.7589 17.1807 14.8069C17.3223 14.8548 17.453 14.9307 17.5651 15.0302C17.6771 15.1297 17.7684 15.2507 17.8334 15.3861C17.8984 15.5216 17.9357 15.6688 17.9435 15.819C17.9548 16.1174 17.8506 16.4084 17.6527 16.6307C17.4548 16.8529 17.1791 16.989 16.8834 17.0101C16.7344 17.0213 16.5844 17.0023 16.4428 16.9544C16.3011 16.9065 16.1704 16.8306 16.0584 16.7311C15.9463 16.6316 15.855 16.5106 15.79 16.3751C15.725 16.2397 15.6877 16.0925 15.6799 15.9423C15.6686 15.6439 15.7728 15.3529 15.9707 15.1306C16.1686 14.9083 16.4448 14.7723 16.7405 14.7511Z" fill="white"/>
<path style="mix-blend-mode:screen" d="M27.1731 41.3643C27.6916 41.3612 28.1929 41.5502 28.5803 41.8949C28.9676 42.2396 29.2135 42.7156 29.2705 43.231C29.2737 43.7495 29.0848 44.2507 28.74 44.6381C28.3953 45.0254 27.9194 45.2713 27.404 45.3283C26.8855 45.3315 26.3842 45.1425 25.9968 44.7977C25.6095 44.453 25.3636 43.977 25.3065 43.4617C25.3034 42.9432 25.4923 42.4419 25.837 42.0545C26.1818 41.6672 26.6577 41.4213 27.1731 41.3643Z" fill="url(#paint3_radial_36_7)"/>
<path d="M27.5406 42.4975C27.69 42.4916 27.8355 42.5439 27.947 42.6435C28.0584 42.7431 28.1267 42.8822 28.1376 43.0313C28.1436 43.1808 28.0913 43.3267 27.9918 43.4382C27.8922 43.5498 27.7532 43.6183 27.6042 43.6292C27.4549 43.6352 27.3093 43.5828 27.1979 43.4832C27.0864 43.3836 27.0182 43.2445 27.0072 43.0954C27.0014 43.0207 27.0104 42.9457 27.0343 42.8748C27.0582 42.8038 27.0965 42.7384 27.1463 42.6826C27.1961 42.6267 27.2567 42.5815 27.3245 42.5497C27.3922 42.5179 27.4659 42.5002 27.5406 42.4975Z" fill="white"/>
<path style="mix-blend-mode:screen" d="M10.8211 46.4612C11.0442 46.4559 11.2608 46.5362 11.4268 46.6856C11.5927 46.835 11.6953 47.0423 11.7135 47.265C11.7207 47.3767 11.7053 47.4887 11.6686 47.5945C11.6319 47.7003 11.5748 47.7976 11.5 47.8808C11.4251 47.9641 11.3341 48.0315 11.2329 48.0791C11.1316 48.1267 11.0222 48.1536 10.9104 48.1581C10.7988 48.1653 10.6867 48.1501 10.581 48.1134C10.4753 48.0767 10.3779 48.0192 10.2947 47.9443C10.2116 47.8694 10.1445 47.7786 10.0969 47.6773C10.0494 47.576 10.0226 47.4662 10.0181 47.3543C10.0108 47.2426 10.0258 47.1305 10.0625 47.0247C10.0992 46.919 10.1567 46.8216 10.2316 46.7384C10.3064 46.6552 10.397 46.5878 10.4982 46.5402C10.5995 46.4926 10.7093 46.4657 10.8211 46.4612Z" fill="url(#paint4_radial_36_7)"/>
<path d="M10.8441 47.0282C10.883 47.0253 10.9219 47.0302 10.9587 47.0425C10.9956 47.0549 11.0294 47.0745 11.058 47.1001C11.0866 47.1257 11.1094 47.1567 11.1249 47.1911C11.1405 47.2256 11.1484 47.2628 11.1483 47.3004C11.1512 47.3362 11.147 47.3722 11.1355 47.4063C11.124 47.4405 11.1056 47.4721 11.0814 47.4993C11.0571 47.5266 11.027 47.5489 10.9938 47.5651C10.9605 47.5813 10.9248 47.591 10.8876 47.5936C10.8105 47.5938 10.736 47.5658 10.6795 47.5153C10.623 47.4648 10.5884 47.3955 10.5829 47.3214C10.5821 47.2504 10.6082 47.1815 10.6562 47.1275C10.7041 47.0736 10.7711 47.0383 10.8441 47.0282Z" fill="white"/>
<path style="mix-blend-mode:screen" d="M36.8722 30.6047C37.0953 30.5994 37.3123 30.6797 37.4782 30.829C37.644 30.9783 37.7462 31.1854 37.7644 31.4079C37.7741 31.6322 37.6954 31.8514 37.5453 32.0183C37.3951 32.1852 37.1856 32.2864 36.9615 32.3002C36.8508 32.31 36.7395 32.2971 36.6339 32.2625C36.5283 32.2279 36.4307 32.1722 36.3473 32.0987C36.2639 32.0253 36.1964 31.9357 36.1487 31.8353C36.1009 31.735 36.0738 31.626 36.0694 31.515C36.0596 31.4019 36.073 31.288 36.1086 31.1802C36.1441 31.0725 36.2012 30.973 36.2763 30.888C36.3514 30.8029 36.4426 30.7339 36.5451 30.6852C36.6476 30.6365 36.7588 30.6091 36.8722 30.6047Z" fill="url(#paint5_radial_36_7)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M66.1396 12.5335L61.9382 1.96123L28.9638 0.359375L25.9083 7.85605L66.1396 12.5335Z" fill="#24D2FF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M81.7352 30.6021L61.9378 1.96094L64.3568 12.3409L81.7352 30.6021Z" fill="#0AB8E5"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M28.9638 0.359375L25.9083 7.85605L3.69193 21.5038L9.80301 13.6227L28.9638 0.359375Z" fill="#0AB8E5"/>
<g style="mix-blend-mode:soft-light">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.69193 21.5033L22.2162 39.6362L68.8768 41.4303L81.7356 30.6018L64.3572 12.3407L25.9083 7.85547L3.69193 21.5033Z" fill="#0A99C0"/>
</g>
<path fill-rule="evenodd" clip-rule="evenodd" d="M54.5542 11.1879L71.487 18.7486L63.6571 9.52197L54.5542 11.1879Z" fill="#7EE5FF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M26.9904 5.229L30.3006 8.36864L21.3886 10.6112L26.9904 5.229Z" fill="#7EE5FF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M61.1109 71.4175L45.4512 74.493L53.3447 75.4542L61.1109 71.4175Z" fill="#28DAF3"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.3411 66.0991L29.282 72.6347L21.6432 71.7376L15.3411 66.0991Z" fill="#28DAF3"/>
<defs>
<radialGradient id="paint0_radial_36_7" cx="0" cy="0" r="1" gradientTransform="matrix(12.7131 47.3852 -36.0943 9.79022 20.0325 23.859)" gradientUnits="userSpaceOnUse">
<stop stop-color="#0FCDEF"/>
<stop offset="1" stop-color="#10AEDA"/>
</radialGradient>
<radialGradient id="paint1_radial_36_7" cx="0" cy="0" r="1" gradientTransform="matrix(-0.0842099 -1.41316 1.4035 -0.0847897 20.6346 23.659)" gradientUnits="userSpaceOnUse">
<stop stop-color="#00B359"/>
<stop offset="0.13" stop-color="#009148"/>
<stop offset="0.34" stop-color="#005E2F"/>
<stop offset="0.54" stop-color="#00351A"/>
<stop offset="0.73" stop-color="#00180C"/>
<stop offset="0.89" stop-color="#000603"/>
<stop offset="1"/>
</radialGradient>
<radialGradient id="paint2_radial_36_7" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(14.1105 6.34213) rotate(-93.4336) scale(3.96474)">
<stop stop-color="#00B359"/>
<stop offset="0.13" stop-color="#009148"/>
<stop offset="0.34" stop-color="#005E2F"/>
<stop offset="0.54" stop-color="#00351A"/>
<stop offset="0.73" stop-color="#00180C"/>
<stop offset="0.89" stop-color="#000603"/>
<stop offset="1"/>
</radialGradient>
<radialGradient id="paint3_radial_36_7" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(25.0662 33.3486) rotate(-93.4336) scale(1.99608)">
<stop stop-color="#00B359"/>
<stop offset="0.13" stop-color="#009148"/>
<stop offset="0.34" stop-color="#005E2F"/>
<stop offset="0.54" stop-color="#00351A"/>
<stop offset="0.73" stop-color="#00180C"/>
<stop offset="0.89" stop-color="#000603"/>
<stop offset="1"/>
</radialGradient>
<radialGradient id="paint4_radial_36_7" cx="0" cy="0" r="1" gradientTransform="matrix(-0.0513971 -0.85738 0.856618 -0.0514428 8.94228 38.8037)" gradientUnits="userSpaceOnUse">
<stop stop-color="#00B359"/>
<stop offset="0.13" stop-color="#009148"/>
<stop offset="0.34" stop-color="#005E2F"/>
<stop offset="0.54" stop-color="#00351A"/>
<stop offset="0.73" stop-color="#00180C"/>
<stop offset="0.89" stop-color="#000603"/>
<stop offset="1"/>
</radialGradient>
<radialGradient id="paint5_radial_36_7" cx="0" cy="0" r="1" gradientTransform="matrix(-0.0513849 -0.856667 0.856416 -0.0514 35.0267 22.9183)" gradientUnits="userSpaceOnUse">
<stop stop-color="#00B359"/>
<stop offset="0.13" stop-color="#009148"/>
<stop offset="0.34" stop-color="#005E2F"/>
<stop offset="0.54" stop-color="#00351A"/>
<stop offset="0.73" stop-color="#00180C"/>
<stop offset="0.89" stop-color="#000603"/>
<stop offset="1"/>
</radialGradient>
</defs>
</svg>

13
assets/images/location.svg

@ -0,0 +1,13 @@
<svg width="51" height="60" viewBox="0 0 51 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22.4452 0.747754C28.8112 -0.0908679 34.7049 1.39966 40.1433 5.23053C45.5567 9.04398 48.7677 14.7022 49.7582 22.2514L49.7584 22.2524C50.0536 24.4941 49.9303 26.9151 49.3799 29.5183C48.8288 32.1247 47.8858 34.8913 46.5471 37.8188C45.209 40.7451 43.4634 43.8205 41.3088 47.0449C39.154 50.2695 36.6274 53.6234 33.7278 57.1056C33.2676 57.6497 32.7211 58.0828 32.087 58.4082C31.4444 58.7378 30.79 58.9454 30.1235 59.0332C29.4571 59.121 28.7719 59.0898 28.0661 58.9379C27.4564 58.8066 26.8902 58.5782 26.366 58.2507L26.1439 58.1046C22.4414 55.4922 19.1325 52.9071 16.216 50.3505C13.2999 47.7942 10.8183 45.2755 8.77 42.7954C6.72094 40.3142 5.0936 37.8863 3.88428 35.5117C2.67651 33.1401 1.92847 30.8337 1.63313 28.5922C0.638668 21.0432 2.27653 14.7456 6.51583 9.66044C10.7744 4.55224 16.0794 1.58646 22.4452 0.747754ZM24.7608 18.3175C22.973 18.5487 21.5214 19.3916 20.4261 20.8319C19.3325 22.2702 18.8948 23.8881 19.1223 25.6647C19.35 27.4437 20.1928 28.896 21.6352 30.0026C23.0775 31.1091 24.6974 31.5464 26.4725 31.3038L26.4714 31.303C28.2537 31.0681 29.706 30.2279 30.8079 28.7942C31.91 27.3601 32.3461 25.7394 32.1088 23.9549C31.8716 22.1711 31.0311 20.7198 29.5995 19.6215C28.1679 18.5232 26.5472 18.0866 24.7608 18.3175Z" fill="url(#paint0_radial_36_498)" stroke="url(#paint1_linear_36_498)" stroke-width="0.770492"/>
<defs>
<radialGradient id="paint0_radial_36_498" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(20.599 12.4721) rotate(78.4712) scale(47.9096 39.6664)">
<stop stop-color="#EB662D"/>
<stop offset="1" stop-color="#D23F00"/>
</radialGradient>
<linearGradient id="paint1_linear_36_498" x1="22.3955" y1="0.366224" x2="30.1742" y2="59.4151" gradientUnits="userSpaceOnUse">
<stop stop-color="#FF6E40"/>
<stop offset="1" stop-color="#C2390D"/>
</linearGradient>
</defs>
</svg>

BIN
assets/images/map_background.png

After

Width: 928  |  Height: 4096  |  Size: 706 KiB

22
assets/images/mission.svg

@ -0,0 +1,22 @@
<svg width="84" height="94" viewBox="0 0 84 94" fill="none" xmlns="http://www.w3.org/2000/svg">
<g opacity="0.3">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.29772 33.7331L0.0819397 69.4865L19.28 88.6446L58.0652 93.1298L77.9118 77.0472L83.3599 30.9138L4.29772 33.7331Z" fill="black" style="mix-blend-mode:multiply"/>
</g>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.14052 57.0558L3.84335 21.815L26.4789 8.16724L67.4693 12.8446L83.3595 30.9136L76.6791 65.7699L54.4328 75.7655L22.1334 72.0492L5.14052 57.0558Z" fill="url(#paint0_radial_36_60)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M67.4699 12.845L63.1893 2.27275L29.5927 0.670898L26.4796 8.16757L67.4699 12.845Z" fill="#F9F9F9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M83.3602 30.9138L63.1893 2.27271L65.6539 12.6527L83.3602 30.9138Z" fill="#B1B1B1"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M29.5921 0.670898L26.4789 8.16757L3.84335 21.8154L10.0697 13.9342L29.5921 0.670898Z" fill="#B1B1B1"/>
<g style="mix-blend-mode:soft-light">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.84335 21.815L22.7171 39.948L70.2582 41.7421L83.3595 30.9136L65.6532 12.6524L26.4789 8.16724L3.84335 21.815Z" fill="#C5C5C5"/>
</g>
<path fill-rule="evenodd" clip-rule="evenodd" d="M55.6657 11.4994L72.918 19.0602L64.9404 9.8335L55.6657 11.4994Z" fill="#EBEBEB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M27.5822 5.54053L30.9548 8.68016L21.8747 10.9228L27.5822 5.54053Z" fill="#EBEBEB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M62.3456 71.729L46.3904 74.8046L54.4329 75.7657L62.3456 71.729Z" fill="#929292"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.713 66.4109L29.9169 72.9464L22.1339 72.0494L15.713 66.4109Z" fill="#929292"/>
<defs>
<radialGradient id="paint0_radial_36_60" cx="0" cy="0" r="1" gradientTransform="matrix(45.2678 5.42067 -4.11525 33.8792 -35.9491 100.749)" gradientUnits="userSpaceOnUse">
<stop stop-color="#D7D7D7"/>
<stop offset="1" stop-color="#AEAEAE"/>
</radialGradient>
</defs>
</svg>

5
lib/common_ui/resources/my_assets.dart

@ -28,4 +28,9 @@ class MyAssets {
static const String correct = 'assets/images/correct.svg'; static const String correct = 'assets/images/correct.svg';
static const String wrong = 'assets/images/wrong.svg'; static const String wrong = 'assets/images/wrong.svg';
static const String handPoint = 'assets/images/hand_point.svg'; static const String handPoint = 'assets/images/hand_point.svg';
static const String mapBackground = 'assets/images/map_background.png';
static const String mission = 'assets/images/mission.svg';
static const String finishedMission = 'assets/images/finished_mission.svg';
static const String currentMission = 'assets/images/current_mission.svg';
static const String location = 'assets/images/location.svg';
} }

13
lib/core/params/home_params.dart

@ -0,0 +1,13 @@
class HomeParams {
int? id;
HomeParams({this.id});
HomeParams copyWith({
int? id,
}) {
return HomeParams(
id: id ?? this.id,
);
}
}

28
lib/features/home/data/datasource/home_datasource.dart

@ -0,0 +1,28 @@
import 'package:hadi_hoda_flutter/core/constants/my_api.dart';
import 'package:hadi_hoda_flutter/core/network/http_request.dart';
import 'package:hadi_hoda_flutter/core/params/home_params.dart';
import 'package:hadi_hoda_flutter/core/response/base_response.dart';
import 'package:hadi_hoda_flutter/features/home/data/model/home_model.dart';
import 'package:hadi_hoda_flutter/features/home/domain/entity/home_entity.dart';
abstract class IHomeDatasource {
Future<HomeEntity> getData({required HomeParams params});
}
class HomeDatasourceImpl implements IHomeDatasource {
final IHttpRequest httpRequest;
const HomeDatasourceImpl(this.httpRequest);
@override
Future<HomeEntity> getData({required HomeParams params}) async {
final response = await httpRequest.get(
path: MyApi.baseUrl,
);
return BaseResponse.getData<HomeEntity>(
response?['data'],
(json) => HomeModel.fromJson(json),
);
}
}

13
lib/features/home/data/model/home_model.dart

@ -0,0 +1,13 @@
import 'package:hadi_hoda_flutter/features/home/domain/entity/home_entity.dart';
class HomeModel extends HomeEntity {
const HomeModel({
super.id,
});
factory HomeModel.fromJson(Map<String, dynamic> json) {
return HomeModel(
id: json['id'],
);
}
}

29
lib/features/home/data/repository_impl/home_repository_impl.dart

@ -0,0 +1,29 @@
import 'package:hadi_hoda_flutter/core/params/home_params.dart';
import 'package:flutter/foundation.dart';
import 'package:hadi_hoda_flutter/core/error_handler/my_exception.dart';
import 'package:hadi_hoda_flutter/core/utils/data_state.dart';
import 'package:hadi_hoda_flutter/features/home/data/datasource/home_datasource.dart';
import 'package:hadi_hoda_flutter/features/home/domain/entity/home_entity.dart';
import 'package:hadi_hoda_flutter/features/home/domain/repository/home_repository.dart';
class HomeRepositoryImpl implements IHomeRepository {
final IHomeDatasource datasource;
const HomeRepositoryImpl(this.datasource);
@override
Future<DataState<HomeEntity, MyException>> getData({required HomeParams params}) async {
try {
final HomeEntity response = await datasource.getData(params: params);
return DataState.success(response);
} on MyException catch (e) {
return DataState.error(e);
} catch (e) {
if (kDebugMode) {
rethrow;
} else {
return DataState.error(MyException(errorMessage: '$e'));
}
}
}
}

14
lib/features/home/domain/entity/home_entity.dart

@ -0,0 +1,14 @@
import 'package:equatable/equatable.dart';
class HomeEntity extends Equatable {
final int? id;
const HomeEntity({
this.id,
});
@override
List<Object?> get props => [
id,
];
}

8
lib/features/home/domain/repository/home_repository.dart

@ -0,0 +1,8 @@
import 'package:hadi_hoda_flutter/core/error_handler/my_exception.dart';
import 'package:hadi_hoda_flutter/core/params/home_params.dart';
import 'package:hadi_hoda_flutter/core/utils/data_state.dart';
import 'package:hadi_hoda_flutter/features/home/domain/entity/home_entity.dart';
abstract class IHomeRepository {
Future<DataState<HomeEntity, MyException>> getData({required HomeParams params});
}

17
lib/features/home/domain/usecases/get_home_usecase.dart

@ -0,0 +1,17 @@
import 'package:hadi_hoda_flutter/core/error_handler/my_exception.dart';
import 'package:hadi_hoda_flutter/core/params/home_params.dart';
import 'package:hadi_hoda_flutter/core/usecase/usecase.dart';
import 'package:hadi_hoda_flutter/core/utils/data_state.dart';
import 'package:hadi_hoda_flutter/features/home/domain/entity/home_entity.dart';
import 'package:hadi_hoda_flutter/features/home/domain/repository/home_repository.dart';
class GetHomeUseCase implements UseCase<HomeEntity, HomeParams> {
final IHomeRepository repository;
const GetHomeUseCase(this.repository);
@override
Future<DataState<HomeEntity, MyException>> call(HomeParams params) {
return repository.getData(params: params);
}
}

41
lib/features/home/presentation/bloc/home_bloc.dart

@ -0,0 +1,41 @@
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:hadi_hoda_flutter/core/status/base_status.dart';
import 'package:hadi_hoda_flutter/features/home/domain/entity/home_entity.dart';
import 'package:hadi_hoda_flutter/features/home/domain/usecases/get_home_usecase.dart';
import 'package:hadi_hoda_flutter/features/home/presentation/bloc/home_event.dart';
import 'package:hadi_hoda_flutter/features/home/presentation/bloc/home_state.dart';
class HomeBloc extends Bloc<HomeEvent, HomeState> {
/// ------------constructor------------
HomeBloc(
this._getHomeUseCase,
) : super(const HomeState()) {
on<GetHomeEvent>(_getHomeEvent);
}
/// ------------UseCases------------
final GetHomeUseCase _getHomeUseCase;
/// ------------Variables------------
/// ------------Controllers------------
/// ------------Functions------------
/// ------------Api Calls------------
FutureOr<void> _getHomeEvent(event, emit) async {
await _getHomeUseCase(event.homeParams).then(
(value) {
value.fold(
(data) {
emit(state.copyWith(getHomeStatus: BaseComplete<HomeEntity>(data)));
},
(error) {
emit(state.copyWith(getHomeStatus: BaseError(error.errorMessage)));
},
);
},
);
}
}

5
lib/features/home/presentation/bloc/home_event.dart

@ -0,0 +1,5 @@
sealed class HomeEvent {
const HomeEvent();
}
class GetHomeEvent extends HomeEvent {}

15
lib/features/home/presentation/bloc/home_state.dart

@ -0,0 +1,15 @@
import 'package:hadi_hoda_flutter/core/status/base_status.dart';
class HomeState {
final BaseStatus getHomeStatus;
const HomeState({this.getHomeStatus = const BaseInit()});
HomeState copyWith({
BaseStatus? getHomeStatus,
}) {
return HomeState(
getHomeStatus: getHomeStatus ?? this.getHomeStatus,
);
}
}

601
lib/features/home/presentation/ui/home_page.dart

@ -0,0 +1,601 @@
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart';
import 'package:hadi_hoda_flutter/core/utils/my_image.dart';
import 'package:hadi_hoda_flutter/core/utils/screen_size.dart';
import 'package:path_drawing/path_drawing.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final ScrollController scrollController = ScrollController();
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
controller: scrollController,
child: Stack(
alignment: Alignment.center,
children: [
MyImage(image: MyAssets.mapBackground, fit: BoxFit.cover),
Positioned(
top: context.heightScreen * 0.16,
left: context.widthScreen * 0.15,
child: Stack(
children: [
CurvyDashedPathPD(
height: 950,
width: context.widthScreen * 0.6,
),
Positioned(
bottom: 30,
right: 80,
child: Stack(
alignment: Alignment.center,
children: [
MyImage(image: MyAssets.mission, size: 43),
Text(
'9',
style: GoogleFonts.marhey(
fontSize: 28,
fontWeight: FontWeight.w400,
color: Colors.white,
),
),
],
),
),
Positioned(
bottom: 70,
left: 20,
child: Stack(
alignment: Alignment.center,
children: [
MyImage(image: MyAssets.mission, size: 43),
Text(
'10',
style: GoogleFonts.marhey(
fontSize: 28,
fontWeight: FontWeight.w400,
color: Colors.white,
),
),
],
),
),
Positioned(
bottom: 150,
left: 50,
child: Stack(
alignment: Alignment.center,
children: [
MyImage(image: MyAssets.mission, size: 43),
Text(
'11',
style: GoogleFonts.marhey(
fontSize: 28,
fontWeight: FontWeight.w400,
color: Colors.white,
),
),
],
),
),
Positioned(
bottom: 180,
left: 140,
child: Stack(
alignment: Alignment.center,
children: [
MyImage(image: MyAssets.mission, size: 43),
Text(
'12',
style: GoogleFonts.marhey(
fontSize: 28,
fontWeight: FontWeight.w400,
color: Colors.white,
),
),
],
),
),
Positioned(
bottom: 260,
right: 20,
child: Stack(
alignment: Alignment.center,
children: [
MyImage(image: MyAssets.mission, size: 43),
Text(
'13',
style: GoogleFonts.marhey(
fontSize: 28,
fontWeight: FontWeight.w400,
color: Colors.white,
),
),
],
),
),
Positioned(
bottom: 370,
right: 30,
child: Stack(
alignment: Alignment.center,
children: [
MyImage(image: MyAssets.mission, size: 43),
Text(
'14',
style: GoogleFonts.marhey(
fontSize: 28,
fontWeight: FontWeight.w400,
color: Colors.white,
),
),
],
),
),
Positioned(
bottom: 420,
left: 40,
child: Stack(
alignment: Alignment.center,
children: [
MyImage(image: MyAssets.mission, size: 43),
Text(
'15',
style: GoogleFonts.marhey(
fontSize: 28,
fontWeight: FontWeight.w400,
color: Colors.white,
),
),
],
),
),
Positioned(
top: 410,
left: 0,
child: Stack(
alignment: Alignment.center,
children: [
MyImage(image: MyAssets.mission, size: 43),
Text(
'16',
style: GoogleFonts.marhey(
fontSize: 28,
fontWeight: FontWeight.w400,
color: Colors.white,
),
),
],
),
),
Positioned(
top: 320,
left: 60,
child: Stack(
alignment: Alignment.center,
children: [
MyImage(image: MyAssets.mission, size: 43),
Text(
'17',
style: GoogleFonts.marhey(
fontSize: 28,
fontWeight: FontWeight.w400,
color: Colors.white,
),
),
],
),
),
Positioned(
top: 220,
left: 80,
child: Stack(
alignment: Alignment.center,
children: [
MyImage(image: MyAssets.mission, size: 43),
Text(
'18',
style: GoogleFonts.marhey(
fontSize: 28,
fontWeight: FontWeight.w400,
color: Colors.white,
),
),
],
),
),
Positioned(
top: 130,
left: 20,
child: Stack(
alignment: Alignment.center,
children: [
MyImage(image: MyAssets.mission, size: 43),
Text(
'19',
style: GoogleFonts.marhey(
fontSize: 28,
fontWeight: FontWeight.w400,
color: Colors.white,
),
),
],
),
),
Positioned(
top: 50,
left: 70,
child: Stack(
alignment: Alignment.center,
children: [
MyImage(image: MyAssets.mission, size: 43),
Text(
'20',
style: GoogleFonts.marhey(
fontSize: 28,
fontWeight: FontWeight.w400,
color: Colors.white,
),
),
],
),
),
],
),
),
Positioned(
bottom: context.heightScreen * 0.12,
left: context.widthScreen * 0.2,
child: Stack(
clipBehavior: Clip.none,
children: [
DottedRoute(
width: context.widthScreen * 0.75,
height: context.heightScreen * 0.65,
),
Positioned(
bottom: -30,
left: 30,
child: Stack(
alignment: Alignment.center,
children: [
MyImage(image: MyAssets.mission, size: 43),
Text(
'1',
style: GoogleFonts.marhey(
fontSize: 28,
fontWeight: FontWeight.w400,
color: Colors.white,
),
),
],
),
),
Positioned(
bottom: 50,
left: 100,
child: Stack(
alignment: Alignment.center,
children: [
MyImage(image: MyAssets.mission, size: 43),
Text(
'2',
style: GoogleFonts.marhey(
fontSize: 28,
fontWeight: FontWeight.w400,
color: Colors.white,
),
),
],
),
),
Positioned(
bottom: 150,
left: 50,
child: Stack(
alignment: Alignment.center,
children: [
MyImage(image: MyAssets.mission, size: 43),
Text(
'3',
style: GoogleFonts.marhey(
fontSize: 28,
fontWeight: FontWeight.w400,
color: Colors.white,
),
),
],
),
),
Positioned(
bottom: 250,
left: 130,
child: Stack(
alignment: Alignment.center,
children: [
MyImage(image: MyAssets.mission, size: 43),
Text(
'4',
style: GoogleFonts.marhey(
fontSize: 28,
fontWeight: FontWeight.w400,
color: Colors.white,
),
),
],
),
),
Positioned(
bottom: 300,
right: 50,
child: Stack(
alignment: Alignment.center,
children: [
MyImage(image: MyAssets.mission, size: 43),
Text(
'5',
style: GoogleFonts.marhey(
fontSize: 28,
fontWeight: FontWeight.w400,
color: Colors.white,
),
),
],
),
),
Positioned(
top: 170,
right: 40,
child: Stack(
alignment: Alignment.center,
children: [
MyImage(image: MyAssets.mission, size: 43),
Text(
'6',
style: GoogleFonts.marhey(
fontSize: 28,
fontWeight: FontWeight.w400,
color: Colors.white,
),
),
],
),
),
Positioned(
top: 70,
right: 70,
child: Stack(
alignment: Alignment.center,
children: [
MyImage(image: MyAssets.mission, size: 43),
Text(
'7',
style: GoogleFonts.marhey(
fontSize: 28,
fontWeight: FontWeight.w400,
color: Colors.white,
),
),
],
),
),
Positioned(
top: -20,
right: 60,
child: Stack(
alignment: Alignment.center,
children: [
MyImage(image: MyAssets.mission, size: 43),
Text(
'8',
style: GoogleFonts.marhey(
fontSize: 28,
fontWeight: FontWeight.w400,
color: Colors.white,
),
),
],
),
),
],
),
),
],
),
),
);
}
}
class DottedRoute extends StatelessWidget {
const DottedRoute({
super.key,
this.width = 500,
this.height = 1523,
this.color = Colors.white,
});
final double width;
final double height;
final Color color;
@override
Widget build(BuildContext context) {
return CustomPaint(
painter: _DottedRoutePainter(color),
size: Size(
width,
height,
), // or Size.infinite inside a parent with constraints
);
}
}
class _DottedRoutePainter extends CustomPainter {
_DottedRoutePainter(this.color);
final Color color;
// SVG viewBox
static const double _vbW = 500;
static const double _vbH = 1523;
// Your SVG path data (unchanged)
static const String _svgPath =
'M1.95892 1520.75C1.95892 1520.75 199.206 1423.63 169.156 1328.9C143.058 1246.63 30.8103 1281.9 15.4421 1225.27C-11.9488 1124.33 48.5736 1164.01 42.795 1033.8C38.5466 938.07 154.913 925.725 219.623 855.048C286.233 782.296 385.022 821.209 446.532 744.097C516.262 656.681 493.917 461.712 493.917 461.712C493.917 461.712 440.122 333.473 428.04 246.36C414.846 151.222 436.901 0.572754 436.901 0.572754';
@override
void paint(Canvas canvas, Size size) {
// Scale SVG viewBox -> current canvas while preserving aspect
final scale = _scaleToFit(
srcW: _vbW,
srcH: _vbH,
dstW: size.width,
dstH: size.height,
);
canvas.translate(
(size.width - _vbW * scale) / 2,
(size.height - _vbH * scale) / 2,
);
canvas.scale(scale);
// Parse and dash the path
final path = parseSvgPathData(_svgPath);
final dashed = dashPath(
path,
dashArray: CircularIntervalList<double>(const [3.08, 13.1]),
);
// Stroke paint
final paint = Paint()
..style = PaintingStyle.stroke
..strokeWidth = 4.62295
..color = color
..strokeCap = StrokeCap.butt
..strokeJoin = StrokeJoin.miter;
canvas.drawPath(dashed, paint);
}
double _scaleToFit({
required double srcW,
required double srcH,
required double dstW,
required double dstH,
}) {
final sx = dstW / srcW;
final sy = dstH / srcH;
return sx < sy ? sx : sy; // contain
}
@override
bool shouldRepaint(covariant _DottedRoutePainter oldDelegate) =>
oldDelegate.color != color;
}
class CurvyDashedPathPD extends StatelessWidget {
const CurvyDashedPathPD({
super.key,
this.width = 604,
this.height = 2651,
this.color = Colors.white,
});
final double width;
final double height;
final Color color;
@override
Widget build(BuildContext context) {
return CustomPaint(
size: Size(width, height),
painter: _CurvyDashedPathPDPainter(color: color),
isComplex: true,
willChange: false,
);
}
}
class _CurvyDashedPathPDPainter extends CustomPainter {
_CurvyDashedPathPDPainter({required this.color});
final Color color;
// SVG viewBox
static const double _vbW = 604.0;
static const double _vbH = 2651.0;
// SVG stroke styling
static const double _strokeWidth = 4.62295;
static const List<double> _dashPattern = [3.08, 13.1];
// The original SVG "d" attribute:
static const String _d = '''
M323.844 1.5163
C323.844 1.5163 254.064 132.635 209.041 216.483
C167.229 294.353 105.588 327.363 101.557 415.655
C96.6703 522.7 235.238 655.278 235.238 655.278
C235.238 655.278 284.393 748.372 277.229 810.918
C270.331 871.151 205.959 948.836 205.959 948.836
C205.959 948.836 31.3055 963.687 11.4099 1046.3
C-1.94798 1101.77 54.9427 1185.76 54.9427 1185.76
C54.9427 1185.76 -32.6228 1326.5 19.8853 1386.09
C63.1414 1435.18 185.541 1411.13 185.541 1411.13
C185.541 1411.13 427.654 1354.52 472.164 1458.9
C492.877 1507.48 472.164 1594.12 472.164 1594.12
C472.164 1594.12 454.029 1680.13 464.844 1733.58
C476.306 1790.23 531.492 1865.72 531.492 1865.72
C531.492 1865.72 515.799 1970.22 472.164 2015.58
C437.994 2051.1 361.598 2076.45 361.598 2076.45
C361.598 2076.45 304.217 2117.23 262.59 2133.08
C221.475 2148.74 152.41 2156.58 152.41 2156.58
C152.41 2156.58 60.2151 2199.32 47.623 2253.66
C34.196 2311.61 108.877 2393.12 108.877 2393.12
C108.877 2393.12 201.293 2437.1 262.59 2460.15
C315.761 2480.15 400.893 2505.23 400.893 2505.23
C400.893 2505.23 509.508 2505.09 553.451 2548.76
C584.574 2579.7 601.221 2650.47 601.221 2650.47
''';
@override
void paint(Canvas canvas, Size size) {
// Scale to widget size
final sx = size.width / _vbW;
final sy = size.height / _vbH;
canvas.save();
canvas.scale(sx, sy);
// Parse SVG path data to a Path
final Path original = parseSvgPathData(_d);
// Apply dash pattern
final Path dashed = dashPath(
original,
dashArray: CircularIntervalList<double>(_dashPattern),
);
// Stroke paint
final paint = Paint()
..style = PaintingStyle.stroke
..strokeWidth = _strokeWidth
..strokeCap = StrokeCap.butt
..strokeJoin = StrokeJoin.miter
..color = color;
canvas.drawPath(dashed, paint);
canvas.restore();
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}

9
lib/init_bindings.dart

@ -1,5 +1,9 @@
import 'package:hadi_hoda_flutter/core/network/http_request.dart'; import 'package:hadi_hoda_flutter/core/network/http_request.dart';
import 'package:hadi_hoda_flutter/core/network/http_request_impl.dart'; import 'package:hadi_hoda_flutter/core/network/http_request_impl.dart';
import 'package:hadi_hoda_flutter/features/home/data/datasource/home_datasource.dart';
import 'package:hadi_hoda_flutter/features/home/data/repository_impl/home_repository_impl.dart';
import 'package:hadi_hoda_flutter/features/home/domain/repository/home_repository.dart';
import 'package:hadi_hoda_flutter/features/home/domain/usecases/get_home_usecase.dart';
import 'package:hadi_hoda_flutter/features/intro/data/datasource/intro_datasource.dart'; import 'package:hadi_hoda_flutter/features/intro/data/datasource/intro_datasource.dart';
import 'package:hadi_hoda_flutter/features/intro/data/repository_impl/intro_repository_impl.dart'; import 'package:hadi_hoda_flutter/features/intro/data/repository_impl/intro_repository_impl.dart';
import 'package:hadi_hoda_flutter/features/intro/domain/repository/intro_repository.dart'; import 'package:hadi_hoda_flutter/features/intro/domain/repository/intro_repository.dart';
@ -34,4 +38,9 @@ void initBindings() {
locator.registerLazySingleton<IQuestionDatasource>(() => QuestionDatasourceImpl(locator())); locator.registerLazySingleton<IQuestionDatasource>(() => QuestionDatasourceImpl(locator()));
locator.registerLazySingleton<IQuestionRepository>(() => QuestionRepositoryImpl(locator())); locator.registerLazySingleton<IQuestionRepository>(() => QuestionRepositoryImpl(locator()));
locator.registerLazySingleton<GetQuestionUseCase>(() => GetQuestionUseCase(locator())); locator.registerLazySingleton<GetQuestionUseCase>(() => GetQuestionUseCase(locator()));
/// Home Feature
locator.registerLazySingleton<IHomeDatasource>(() => HomeDatasourceImpl(locator()));
locator.registerLazySingleton<IHomeRepository>(() => HomeRepositoryImpl(locator()));
locator.registerLazySingleton<GetHomeUseCase>(() => GetHomeUseCase(locator()));
} }

12
pubspec.lock

@ -29,10 +29,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: bloc name: bloc
sha256: "52c10575f4445c61dd9e0cafcc6356fdd827c4c64dd7945ef3c4105f6b6ac189"
sha256: e18b8e7825e9921d67a6d256dba0b6015ece8a577eb0a411845c46a352994d78
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "9.0.0"
version: "9.0.1"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
@ -317,6 +317,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.9.1" version: "1.9.1"
path_drawing:
dependency: "direct main"
description:
name: path_drawing
sha256: bbb1934c0cbb03091af082a6389ca2080345291ef07a5fa6d6e078ba8682f977
url: "https://pub.dev"
source: hosted
version: "1.0.1"
path_parsing: path_parsing:
dependency: transitive dependency: transitive
description: description:

1
pubspec.yaml

@ -21,6 +21,7 @@ dependencies:
go_router: ^16.1.0 go_router: ^16.1.0
google_fonts: ^6.3.2 google_fonts: ^6.3.2
intl: ^0.20.2 intl: ^0.20.2
path_drawing: ^1.0.1
pretty_dio_logger: ^1.4.0 pretty_dio_logger: ^1.4.0
shared_preferences: ^2.5.3 shared_preferences: ^2.5.3
showcaseview: ^4.0.1 showcaseview: ^4.0.1

Loading…
Cancel
Save