added discover
This commit is contained in:
parent
d994b45735
commit
fb2119548e
|
|
@ -0,0 +1,13 @@
|
||||||
|
<svg width="26" height="40" viewBox="0 0 26 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_2117_5938)">
|
||||||
|
<path d="M13.1922 38.7643C13.8673 38.2494 14.2906 37.5171 14.7941 36.8535C16.4188 34.7368 18.2265 32.7689 19.7712 30.5835C21.167 28.6041 22.0366 26.4645 21.8764 23.9702C21.6247 19.9428 18.238 16.2471 14.2334 15.7322C9.06179 15.0686 4.73685 18.2265 3.85585 23.3638C3.46683 25.6522 4.10756 27.7345 5.29749 29.6796C6.38445 31.4645 7.79177 32.9977 9.08468 34.6224C9.56523 35.2288 10.0458 35.8352 10.5263 36.4416C10.3433 36.6018 10.1945 36.5446 10.0458 36.5446C7.07095 36.5446 4.09612 36.5446 1.12129 36.5446C0.18308 36.5446 -0.0800782 36.2929 -0.0114284 35.3547C0.308938 30.6636 0.617862 25.9725 0.915345 21.2814C1.12129 18.0549 1.33869 14.8169 1.52175 11.5904C1.62473 9.78259 1.67049 9.7025 3.47827 9.7025C4.59955 9.7025 4.59955 9.7025 4.59955 10.8352C4.59955 11.3043 4.58811 11.762 4.38216 12.2197C4.09612 12.8833 4.3936 13.6613 4.97713 14.0847C5.57209 14.508 6.40733 14.4966 7.0023 14.0389C7.57438 13.6041 7.8261 12.8146 7.51717 12.1396C7.18536 11.4187 7.37987 10.675 7.34555 9.94278C7.32266 9.5652 7.66591 9.69106 7.86042 9.69106C10.286 9.67962 12.7002 9.67962 15.1259 9.67962C16.0412 9.67962 16.9565 9.69106 17.8719 9.66818C18.2494 9.65674 18.3753 9.78259 18.341 10.1602C18.2838 10.8696 18.3982 11.5789 18.1121 12.2883C17.8375 12.9863 18.1922 13.73 18.8101 14.119C19.4279 14.508 20.2403 14.4622 20.778 14.0046C21.3501 13.5355 21.5789 12.7689 21.2586 12.0938C20.9268 11.373 21.1442 10.6293 21.0755 9.89701C21.0526 9.67962 21.2357 9.66818 21.3959 9.66818C22.0023 9.66818 22.6201 9.64529 23.2265 9.67962C23.7643 9.71394 24.0389 10.0458 24.0732 10.5835C24.1762 12.1052 24.2792 13.627 24.3821 15.1487C24.7254 20.3203 25.0572 25.492 25.389 30.6521C25.492 32.254 25.5835 33.8444 25.6636 35.4462C25.7094 36.2357 25.4348 36.5331 24.6339 36.5331C22.4828 36.5331 20.3318 36.5446 18.1693 36.5331C17.8146 36.5331 17.5057 36.6132 17.2082 36.7963C16.1327 37.4485 15.0572 38.0892 13.9703 38.7299C13.6499 38.9016 13.3295 39.0732 12.8719 39.302C13.0549 39.0503 13.2037 38.9473 13.1922 38.7643Z" fill="#0E3F66"/>
|
||||||
|
<path d="M6.25858 24.6796C6.25858 21.0526 9.22196 18.1236 12.8604 18.135C16.476 18.1465 19.405 21.0526 19.4279 24.6682C19.4508 28.3181 16.4645 31.3043 12.8261 31.2929C9.18764 31.27 6.24714 28.3066 6.25858 24.6796Z" fill="#2196F3"/>
|
||||||
|
<path d="M20.7323 9.27917C20.7323 10.0229 20.7323 10.595 20.7323 11.167C20.7323 11.5217 20.7552 11.8535 20.9497 12.1968C21.2358 12.7002 20.9726 13.3982 20.4348 13.7986C19.9772 14.1419 19.4165 14.1304 18.9589 13.7757C18.4326 13.3638 18.1923 12.6659 18.4898 12.1625C18.6614 11.8535 18.6957 11.5561 18.6843 11.2357C18.6385 9.74828 18.833 8.26086 18.5699 6.78489C18.0321 3.9016 15.2747 1.7849 12.4486 2.04805C9.35933 2.33409 7.03668 4.77116 6.99091 7.78032C6.96803 9.01601 6.99091 10.2517 6.99091 11.4988C6.99091 11.6934 7.02524 11.865 7.11677 12.0366C7.46002 12.643 7.29984 13.3066 6.72776 13.7643C6.23577 14.1533 5.6408 14.1533 5.16025 13.7414C4.61105 13.2723 4.46231 12.6316 4.817 12.0137C4.94286 11.7963 4.91998 11.5789 4.93142 11.3501C4.98863 9.77116 4.80556 8.18077 5.03439 6.61327C5.60648 2.86041 8.9932 0 12.849 0C16.682 0 20.0344 2.87185 20.6294 6.60183C20.7781 7.55148 20.698 8.50114 20.7323 9.27917Z" fill="#2196F3"/>
|
||||||
|
<path d="M13.1922 38.7643C13.2037 38.9473 13.0549 39.0618 12.8833 39.3364C13.341 39.0961 13.6613 38.9245 13.9817 38.7643C14.6568 38.9817 15.3776 38.7986 16.0526 38.9817C16.3616 39.0618 16.6934 39.0732 17.0023 39.1418C17.1396 39.1762 17.3341 39.2334 17.357 39.3936C17.3799 39.5995 17.1396 39.5995 17.0137 39.6224C16.5561 39.7254 16.087 39.8169 15.6179 39.8627C13.341 40.1029 11.0755 40.0572 8.82152 39.6682C8.63845 39.6338 8.32953 39.6338 8.32953 39.3936C8.34097 39.1876 8.62701 39.1418 8.83296 39.0961C10.2746 38.8444 11.7391 38.7414 13.1922 38.7643Z" fill="#D8D8D8"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_2117_5938">
|
||||||
|
<rect width="25.675" height="40" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.9 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 6.1 KiB |
|
|
@ -0,0 +1,5 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M12 6.44V9.77" stroke="#666666" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||||
|
<path d="M12.02 2C8.34002 2 5.36002 4.98 5.36002 8.66V10.76C5.36002 11.44 5.08002 12.46 4.73002 13.04L3.46002 15.16C2.68002 16.47 3.22002 17.93 4.66002 18.41C9.44002 20 14.61 20 19.39 18.41C20.74 17.96 21.32 16.38 20.59 15.16L19.32 13.04C18.97 12.46 18.69 11.43 18.69 10.76V8.66C18.68 5 15.68 2 12.02 2Z" stroke="#666666" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round"/>
|
||||||
|
<path d="M15.33 18.82C15.33 20.65 13.83 22.15 12 22.15C11.09 22.15 10.25 21.77 9.65004 21.17C9.05004 20.57 8.67004 19.73 8.67004 18.82" stroke="#666666" stroke-width="1.5" stroke-miterlimit="10"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 797 B |
|
|
@ -0,0 +1,10 @@
|
||||||
|
<svg width="26" height="19" viewBox="0 0 26 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_2086_4980)">
|
||||||
|
<path d="M13.5376 0.960446C13.8786 0.139446 15.0426 0.139446 15.3836 0.960446L15.8636 2.11245L17.1066 2.21245C17.9926 2.28245 18.3526 3.38945 17.6766 3.96845L16.7296 4.77945L17.0196 5.99345C17.2256 6.85845 16.2846 7.54245 15.5256 7.07845L14.4606 6.42845L13.3956 7.07845C12.6366 7.54245 11.6956 6.85845 11.9016 5.99345L12.1916 4.77945L11.2446 3.96845C10.5686 3.38945 10.9276 2.28345 11.8146 2.21145L13.0586 2.11145L13.5376 0.960446ZM14.9396 2.49645L14.4606 1.34445L13.9806 2.49645C13.9101 2.66611 13.7943 2.81308 13.6457 2.92122C13.4972 3.02935 13.3218 3.09448 13.1386 3.10945L11.8946 3.20945L12.8416 4.01945C12.9816 4.13905 13.0858 4.29496 13.1428 4.46999C13.1997 4.64502 13.2073 4.83239 13.1646 5.01145L12.8746 6.22545L13.9396 5.57545C14.0965 5.47967 14.2768 5.429 14.4606 5.429C14.6445 5.429 14.8247 5.47967 14.9816 5.57545L16.0466 6.22545L15.7566 5.01145C15.7142 4.83253 15.7218 4.64537 15.7788 4.47054C15.8358 4.2957 15.9399 4.13996 16.0796 4.02045L17.0266 3.20845L15.7836 3.10845C15.6003 3.09392 15.4245 3.02911 15.2756 2.92113C15.1267 2.81316 15.0104 2.66621 14.9396 2.49645ZM8.53764 6.96045C8.87864 6.13945 10.0426 6.13945 10.3836 6.96045L11.6566 10.0204L14.9596 10.2844C15.8466 10.3554 16.2056 11.4624 15.5296 12.0414L13.0136 14.1964L13.7836 17.4204C13.9886 18.2854 13.0476 18.9694 12.2886 18.5054L9.46064 16.7784L6.63264 18.5054C5.87364 18.9694 4.93264 18.2854 5.13864 17.4204L5.90864 14.1964L3.39064 12.0424C2.71564 11.4634 3.07464 10.3564 3.96164 10.2854L7.26464 10.0214L8.53764 6.96045ZM10.7336 10.4044L9.46064 7.34445L8.18864 10.4044C8.11785 10.5742 8.00161 10.7212 7.8527 10.8291C7.7038 10.9371 7.528 11.0019 7.34464 11.0164L4.04164 11.2814L6.55864 13.4374C6.69839 13.5572 6.80239 13.7131 6.85921 13.8881C6.91602 14.0632 6.92344 14.2505 6.88064 14.4294L6.11064 17.6524L8.93964 15.9254C9.09655 15.8297 9.27682 15.779 9.46064 15.779C9.64447 15.779 9.82474 15.8297 9.98164 15.9254L12.8096 17.6524L12.0416 14.4294C11.9988 14.2505 12.0063 14.0632 12.0631 13.8881C12.1199 13.7131 12.2239 13.5572 12.3636 13.4374L14.8796 11.2814L11.5766 11.0164C11.3935 11.0017 11.2179 10.9368 11.0692 10.8289C10.9204 10.7209 10.8044 10.5741 10.7336 10.4044ZM19.9136 6.83145C19.8734 6.74527 19.8094 6.67237 19.7291 6.62129C19.6489 6.57021 19.5558 6.54309 19.4606 6.54309C19.3655 6.54309 19.2724 6.57021 19.1921 6.62129C19.1119 6.67237 19.0479 6.74527 19.0076 6.83145L18.1296 8.71145L16.2496 9.58945C16.1635 9.62971 16.0906 9.69371 16.0395 9.77395C15.9884 9.85419 15.9613 9.94733 15.9613 10.0424C15.9613 10.1376 15.9884 10.2307 16.0395 10.3109C16.0906 10.3912 16.1635 10.4552 16.2496 10.4954L18.1296 11.3734L19.0076 13.2534C19.0479 13.3396 19.1119 13.4125 19.1921 13.4636C19.2724 13.5147 19.3655 13.5418 19.4606 13.5418C19.5558 13.5418 19.6489 13.5147 19.7291 13.4636C19.8094 13.4125 19.8734 13.3396 19.9136 13.2534L20.7916 11.3734L22.6716 10.4954C22.7578 10.4552 22.8307 10.3912 22.8818 10.3109C22.9329 10.2307 22.96 10.1376 22.96 10.0424C22.96 9.94733 22.9329 9.85419 22.8818 9.77395C22.8307 9.69371 22.7578 9.62971 22.6716 9.58945L20.7916 8.71145L19.9136 6.83145ZM18.9596 9.29945L19.4606 8.22445L19.9626 9.29945C20.0121 9.4059 20.0974 9.49157 20.2036 9.54145L21.2786 10.0424L20.2036 10.5444C20.0976 10.5941 20.0123 10.6794 19.9626 10.7854L19.4606 11.8604L18.9586 10.7854C18.9092 10.679 18.8239 10.5933 18.7176 10.5434L17.6426 10.0424L18.7176 9.54045C18.8237 9.49082 18.909 9.40553 18.9586 9.29945" fill="#0E3F66"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_2086_4980">
|
||||||
|
<rect width="24.8544" height="18" fill="white" transform="translate(0.572815 0.5)"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.6 KiB |
|
|
@ -15,6 +15,9 @@ import 'package:vector_graphics/vector_graphics.dart' as _vg;
|
||||||
class $AssetsIconsGen {
|
class $AssetsIconsGen {
|
||||||
const $AssetsIconsGen();
|
const $AssetsIconsGen();
|
||||||
|
|
||||||
|
/// File path: assets/icons/LBA Logo.svg
|
||||||
|
SvgGenImage get lBALogo => const SvgGenImage('assets/icons/LBA Logo.svg');
|
||||||
|
|
||||||
/// File path: assets/icons/Line 1.svg
|
/// File path: assets/icons/Line 1.svg
|
||||||
SvgGenImage get line1 => const SvgGenImage('assets/icons/Line 1.svg');
|
SvgGenImage get line1 => const SvgGenImage('assets/icons/Line 1.svg');
|
||||||
|
|
||||||
|
|
@ -46,6 +49,9 @@ class $AssetsIconsGen {
|
||||||
/// File path: assets/icons/Shop2.svg
|
/// File path: assets/icons/Shop2.svg
|
||||||
SvgGenImage get shop2 => const SvgGenImage('assets/icons/Shop2.svg');
|
SvgGenImage get shop2 => const SvgGenImage('assets/icons/Shop2.svg');
|
||||||
|
|
||||||
|
/// File path: assets/icons/Winter.svg
|
||||||
|
SvgGenImage get winter => const SvgGenImage('assets/icons/Winter.svg');
|
||||||
|
|
||||||
/// File path: assets/icons/arrow-down-black.svg
|
/// File path: assets/icons/arrow-down-black.svg
|
||||||
SvgGenImage get arrowDownBlack =>
|
SvgGenImage get arrowDownBlack =>
|
||||||
const SvgGenImage('assets/icons/arrow-down-black.svg');
|
const SvgGenImage('assets/icons/arrow-down-black.svg');
|
||||||
|
|
@ -165,6 +171,10 @@ class $AssetsIconsGen {
|
||||||
/// File path: assets/icons/next.svg
|
/// File path: assets/icons/next.svg
|
||||||
SvgGenImage get next => const SvgGenImage('assets/icons/next.svg');
|
SvgGenImage get next => const SvgGenImage('assets/icons/next.svg');
|
||||||
|
|
||||||
|
/// File path: assets/icons/notification-bing.svg
|
||||||
|
SvgGenImage get notificationBing =>
|
||||||
|
const SvgGenImage('assets/icons/notification-bing.svg');
|
||||||
|
|
||||||
/// 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');
|
||||||
|
|
||||||
|
|
@ -224,6 +234,10 @@ class $AssetsIconsGen {
|
||||||
/// File path: assets/icons/star.svg
|
/// File path: assets/icons/star.svg
|
||||||
SvgGenImage get star => const SvgGenImage('assets/icons/star.svg');
|
SvgGenImage get star => const SvgGenImage('assets/icons/star.svg');
|
||||||
|
|
||||||
|
/// File path: assets/icons/stash_stars-light.svg
|
||||||
|
SvgGenImage get stashStarsLight =>
|
||||||
|
const SvgGenImage('assets/icons/stash_stars-light.svg');
|
||||||
|
|
||||||
/// File path: assets/icons/tick.svg
|
/// File path: assets/icons/tick.svg
|
||||||
SvgGenImage get tick => const SvgGenImage('assets/icons/tick.svg');
|
SvgGenImage get tick => const SvgGenImage('assets/icons/tick.svg');
|
||||||
|
|
||||||
|
|
@ -240,6 +254,7 @@ class $AssetsIconsGen {
|
||||||
|
|
||||||
/// List of all assets
|
/// List of all assets
|
||||||
List<SvgGenImage> get values => [
|
List<SvgGenImage> get values => [
|
||||||
|
lBALogo,
|
||||||
line1,
|
line1,
|
||||||
line4,
|
line4,
|
||||||
mDSPublicTWButton,
|
mDSPublicTWButton,
|
||||||
|
|
@ -249,6 +264,7 @@ class $AssetsIconsGen {
|
||||||
shape,
|
shape,
|
||||||
shop,
|
shop,
|
||||||
shop2,
|
shop2,
|
||||||
|
winter,
|
||||||
arrowDownBlack,
|
arrowDownBlack,
|
||||||
arrowDown,
|
arrowDown,
|
||||||
arrowLeft,
|
arrowLeft,
|
||||||
|
|
@ -284,6 +300,7 @@ class $AssetsIconsGen {
|
||||||
nearby,
|
nearby,
|
||||||
nearby2,
|
nearby2,
|
||||||
next,
|
next,
|
||||||
|
notificationBing,
|
||||||
phCheese,
|
phCheese,
|
||||||
profile2,
|
profile2,
|
||||||
profile,
|
profile,
|
||||||
|
|
@ -302,6 +319,7 @@ class $AssetsIconsGen {
|
||||||
starFill,
|
starFill,
|
||||||
starHalf,
|
starHalf,
|
||||||
star,
|
star,
|
||||||
|
stashStarsLight,
|
||||||
tick,
|
tick,
|
||||||
timerPause,
|
timerPause,
|
||||||
timerStart,
|
timerStart,
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'features/auth/presentation/pages/onboarding_page.dart';
|
import 'features/auth/presentation/pages/onboarding_page.dart';
|
||||||
|
import 'widgets/animated_splash_screen.dart';
|
||||||
import 'injection_container.dart';
|
import 'injection_container.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|
@ -29,9 +30,7 @@ class MyApp extends StatelessWidget {
|
||||||
appBarTheme: const AppBarTheme(
|
appBarTheme: const AppBarTheme(
|
||||||
backgroundColor: Color.fromARGB(255, 14, 63, 102),
|
backgroundColor: Color.fromARGB(255, 14, 63, 102),
|
||||||
),
|
),
|
||||||
dialogTheme: DialogTheme(
|
dialogTheme: DialogTheme(backgroundColor: Colors.white),
|
||||||
backgroundColor: Colors.white,
|
|
||||||
),
|
|
||||||
dropdownMenuTheme: DropdownMenuThemeData(
|
dropdownMenuTheme: DropdownMenuThemeData(
|
||||||
menuStyle: MenuStyle(
|
menuStyle: MenuStyle(
|
||||||
backgroundColor: MaterialStatePropertyAll(Colors.white),
|
backgroundColor: MaterialStatePropertyAll(Colors.white),
|
||||||
|
|
@ -44,11 +43,23 @@ class MyApp extends StatelessWidget {
|
||||||
borderSide: BorderSide(color: Colors.grey),
|
borderSide: BorderSide(color: Colors.grey),
|
||||||
),
|
),
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: OutlineInputBorder(
|
||||||
borderSide: BorderSide(color: Color.fromARGB(255, 14, 63, 102), width: 2),
|
borderSide: BorderSide(
|
||||||
|
color: Color.fromARGB(255, 14, 63, 102),
|
||||||
|
width: 2,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
home: const OnboardingPage(),
|
pageTransitionsTheme: const PageTransitionsTheme(
|
||||||
|
builders: {
|
||||||
|
TargetPlatform.android: CupertinoPageTransitionsBuilder(),
|
||||||
|
TargetPlatform.iOS: CupertinoPageTransitionsBuilder(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
home: CoolSplashScreen(
|
||||||
|
nextScreen: const OnboardingPage(),
|
||||||
|
duration: const Duration(seconds: 6),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,4 +17,8 @@ class LightAppColors{
|
||||||
static const fillOrder = Color.fromARGB(255, 200, 230, 201);
|
static const fillOrder = Color.fromARGB(255, 200, 230, 201);
|
||||||
static const fillOrderText = Color.fromARGB(255, 32, 74, 34);
|
static const fillOrderText = Color.fromARGB(255, 32, 74, 34);
|
||||||
static const allReviewOpener = Color.fromARGB(255, 183, 28, 28);
|
static const allReviewOpener = Color.fromARGB(255, 183, 28, 28);
|
||||||
|
static const hintTitle = Color.fromARGB(255, 73, 69, 79);
|
||||||
|
static const cardBackground = Color.fromARGB(255, 242, 242, 241);
|
||||||
|
static const offerTimer = Color.fromARGB(255, 244, 67, 54);
|
||||||
|
static const offerCardDetail = Color.fromARGB(255, 73, 69, 79);
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -21,11 +21,11 @@ class _MainScreenState extends State<MainScreen> {
|
||||||
int _currentIndex = 0;
|
int _currentIndex = 0;
|
||||||
|
|
||||||
final List<Widget> _screens = [
|
final List<Widget> _screens = [
|
||||||
Nearby(),
|
const Nearby(),
|
||||||
Discover(),
|
const Discover(),
|
||||||
Hunt(),
|
const Hunt(),
|
||||||
Planner(),
|
const Planner(),
|
||||||
Profile(),
|
const Profile(),
|
||||||
];
|
];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -33,9 +33,34 @@ class _MainScreenState extends State<MainScreen> {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
extendBody: true,
|
extendBody: true,
|
||||||
body: AnimatedSwitcher(
|
body: AnimatedSwitcher(
|
||||||
duration: const Duration(milliseconds: 300),
|
duration: const Duration(milliseconds: 400),
|
||||||
|
transitionBuilder: (Widget child, Animation<double> animation) {
|
||||||
|
final bool isGoingForward =
|
||||||
|
(child.key as ValueKey<int>).value > _currentIndex;
|
||||||
|
|
||||||
|
final slideAnimation = Tween<Offset>(
|
||||||
|
begin: Offset(isGoingForward ? 1.0 : -1.0, 0.0),
|
||||||
|
end: Offset.zero,
|
||||||
|
).animate(
|
||||||
|
CurvedAnimation(
|
||||||
|
parent: animation,
|
||||||
|
curve: Curves.easeInOutCubic,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return SlideTransition(
|
||||||
|
position: slideAnimation,
|
||||||
|
child: FadeTransition(
|
||||||
|
opacity: animation,
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: KeyedSubtree(
|
||||||
|
key: ValueKey<int>(_currentIndex),
|
||||||
child: _screens[_currentIndex],
|
child: _screens[_currentIndex],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
bottomNavigationBar: CustomBottomNavigationBar(
|
bottomNavigationBar: CustomBottomNavigationBar(
|
||||||
onTap: (int index) {
|
onTap: (int index) {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,65 @@ 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';
|
||||||
|
|
||||||
class Bestnearby extends StatelessWidget {
|
class Bestnearby extends StatefulWidget {
|
||||||
const Bestnearby({super.key,});
|
const Bestnearby({
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<Bestnearby> createState() => _BestnearbyState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _BestnearbyState extends State<Bestnearby>
|
||||||
|
with SingleTickerProviderStateMixin {
|
||||||
|
late AnimationController _controller;
|
||||||
|
late List<Animation<double>> _staggeredAnimations;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
_controller = AnimationController(
|
||||||
|
vsync: this,
|
||||||
|
duration: const Duration(milliseconds: 1500),
|
||||||
|
);
|
||||||
|
|
||||||
|
// --- انیمیشنهای مرحلهای برای هر بخش ---
|
||||||
|
_staggeredAnimations = List.generate(3, (index) {
|
||||||
|
return Tween<double>(begin: 0.0, end: 1.0).animate(
|
||||||
|
CurvedAnimation(
|
||||||
|
parent: _controller,
|
||||||
|
curve: Interval(
|
||||||
|
(0.2 * index),
|
||||||
|
(0.6 + 0.2 * index).clamp(0.0, 1.0),
|
||||||
|
curve: Curves.easeOutCubic,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
_controller.forward();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_controller.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- ویجت انیمیشنی برای هر بخش ---
|
||||||
|
Widget _buildAnimatedSection(Widget child, int index) {
|
||||||
|
return FadeTransition(
|
||||||
|
opacity: _staggeredAnimations[index],
|
||||||
|
child: SlideTransition(
|
||||||
|
position: Tween<Offset>(
|
||||||
|
begin: const Offset(0.0, 0.5),
|
||||||
|
end: Offset.zero,
|
||||||
|
).animate(_staggeredAnimations[index]),
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
@ -18,16 +75,18 @@ class Bestnearby extends StatelessWidget {
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
Assets.icons.back.path,
|
Assets.icons.back.path,
|
||||||
fit: BoxFit.scaleDown,
|
fit: BoxFit.scaleDown,
|
||||||
|
color: Colors.black,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
title: const Text("Top Deals & Stores", style: TextStyle(fontSize: 18)),
|
title: const Text("Top Deals & Stores",
|
||||||
|
style: TextStyle(fontSize: 18, color: Colors.black)),
|
||||||
),
|
),
|
||||||
body: SingleChildScrollView(
|
body: SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
NearbyItems(detailsType: 0),
|
_buildAnimatedSection(NearbyItems(detailsType: 0), 0),
|
||||||
NearbyItems(detailsType: 1),
|
_buildAnimatedSection(NearbyItems(detailsType: 1), 1),
|
||||||
NearbyItems(detailsType: 2)
|
_buildAnimatedSection(NearbyItems(detailsType: 2), 2),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -35,25 +94,84 @@ class Bestnearby extends StatelessWidget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NearbyItems extends StatelessWidget {
|
class NearbyItems extends StatefulWidget {
|
||||||
const NearbyItems({super.key, required this.detailsType});
|
const NearbyItems({super.key, required this.detailsType});
|
||||||
|
|
||||||
final int detailsType;
|
final int detailsType;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<NearbyItems> createState() => _NearbyItemsState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _NearbyItemsState extends State<NearbyItems>
|
||||||
|
with SingleTickerProviderStateMixin {
|
||||||
|
late AnimationController _listController;
|
||||||
|
late List<Animation<double>> _itemAnimations;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_listController = AnimationController(
|
||||||
|
vsync: this,
|
||||||
|
duration: const Duration(milliseconds: 1000),
|
||||||
|
);
|
||||||
|
|
||||||
|
_itemAnimations = List.generate(5, (index) {
|
||||||
|
return Tween<double>(begin: 0.0, end: 1.0).animate(
|
||||||
|
CurvedAnimation(
|
||||||
|
parent: _listController,
|
||||||
|
curve: Interval(
|
||||||
|
(0.15 * index),
|
||||||
|
(0.5 + 0.15 * index).clamp(0.0, 1.0),
|
||||||
|
curve: Curves.easeInOut,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
_listController.forward();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_listController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildAnimatedItem(Widget child, int index) {
|
||||||
|
return FadeTransition(
|
||||||
|
opacity: _itemAnimations[index],
|
||||||
|
child: SlideTransition(
|
||||||
|
position: Tween<Offset>(
|
||||||
|
begin: const Offset(0.3, 0.0),
|
||||||
|
end: Offset.zero,
|
||||||
|
).animate(_itemAnimations[index]),
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
DividerTitle(detailsType: detailsType),
|
DividerTitle(detailsType: widget.detailsType),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: detailsType==0?180:detailsType==1?240:detailsType==2?240:200,
|
height: widget.detailsType == 0
|
||||||
|
? 180
|
||||||
|
: widget.detailsType == 1
|
||||||
|
? 240
|
||||||
|
: widget.detailsType == 2
|
||||||
|
? 240
|
||||||
|
: 200,
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
itemCount: 5,
|
itemCount: 5,
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
return Padding(
|
return _buildAnimatedItem(
|
||||||
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
|
@ -76,8 +194,8 @@ class NearbyItems extends StatelessWidget {
|
||||||
style: TextStyle(fontWeight: FontWeight.bold),
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
detailsType == 0
|
if (widget.detailsType == 0)
|
||||||
? Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(Assets.icons.routing.path),
|
SvgPicture.asset(Assets.icons.routing.path),
|
||||||
SizedBox(width: 4),
|
SizedBox(width: 4),
|
||||||
|
|
@ -87,15 +205,16 @@ class NearbyItems extends StatelessWidget {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
: detailsType == 1
|
else if (widget.detailsType == 1)
|
||||||
? Column(
|
Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(height: 2),
|
SizedBox(height: 2),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(Assets.icons.category2.path),
|
SvgPicture.asset(
|
||||||
|
Assets.icons.category2.path),
|
||||||
SizedBox(width: 4),
|
SizedBox(width: 4),
|
||||||
Text("Stationery store"),
|
Text("Stationery store"),
|
||||||
],
|
],
|
||||||
|
|
@ -123,8 +242,8 @@ class NearbyItems extends StatelessWidget {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
: detailsType == 2
|
else if (widget.detailsType == 2)
|
||||||
? Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(height: 2),
|
SizedBox(height: 2),
|
||||||
|
|
@ -158,9 +277,10 @@ class NearbyItems extends StatelessWidget {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
: SizedBox(),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
index,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
@ -186,7 +306,11 @@ class DividerTitle extends StatelessWidget {
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
detailsType==0?"Highest Discount Areas":detailsType==1?"Highest Discount Areas":detailsType==2?"Best Deal, Don't Miss":"",
|
detailsType == 0
|
||||||
|
? "Highest Discount Areas"
|
||||||
|
: detailsType == 1
|
||||||
|
? "Highest Discount Areas"
|
||||||
|
: "Best Deal, Don't Miss",
|
||||||
style: TextStyle(fontSize: 15),
|
style: TextStyle(fontSize: 15),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
// ignore_for_file: library_private_types_in_public_api, avoid_print
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_map/flutter_map.dart';
|
import 'package:flutter_map/flutter_map.dart';
|
||||||
import 'package:latlong2/latlong.dart';
|
import 'package:latlong2/latlong.dart';
|
||||||
|
|
|
||||||
|
|
@ -16,16 +16,13 @@ class Nearby extends StatefulWidget {
|
||||||
State<Nearby> createState() => _NearbyState();
|
State<Nearby> createState() => _NearbyState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _NearbyState extends State<Nearby> {
|
class _NearbyState extends State<Nearby> with TickerProviderStateMixin {
|
||||||
String selectedOption = "Relevance";
|
String selectedOption = "Relevance";
|
||||||
final List<String> options = ["Relevance", "Newest", "Oldest", "Popularity"];
|
final List<String> options = ["Relevance", "Newest", "Oldest", "Popularity"];
|
||||||
int selectedIndex = 1;
|
int selectedIndex = 1;
|
||||||
List<String> selectedOptions = [];
|
List<String> selectedOptions = [];
|
||||||
|
|
||||||
@override
|
late AnimationController _listAnimationController;
|
||||||
void dispose() {
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
|
@ -35,6 +32,31 @@ class _NearbyState extends State<Nearby> {
|
||||||
showGPSDialog(context);
|
showGPSDialog(context);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_listAnimationController = AnimationController(
|
||||||
|
vsync: this,
|
||||||
|
duration: const Duration(milliseconds: 1000),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (selectedIndex == 1) {
|
||||||
|
_listAnimationController.forward();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_listAnimationController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onToggle(int index) {
|
||||||
|
setState(() {
|
||||||
|
selectedIndex = index;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (index == 1) {
|
||||||
|
_listAnimationController.forward(from: 0.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -125,12 +147,29 @@ class _NearbyState extends State<Nearby> {
|
||||||
color: const Color.fromARGB(255, 14, 63, 102),
|
color: const Color.fromARGB(255, 14, 63, 102),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: selectedIndex == 1 ? _buildListContent() : CustomMap(),
|
child: AnimatedSwitcher(
|
||||||
|
duration: const Duration(milliseconds: 500),
|
||||||
|
transitionBuilder: (Widget child, Animation<double> animation) {
|
||||||
|
final slideAnimation = Tween<Offset>(
|
||||||
|
begin: Offset(child.key == const ValueKey('list') ? -1.0 : 1.0, 0.0),
|
||||||
|
end: Offset.zero,
|
||||||
|
).animate(CurvedAnimation(parent: animation, curve: Curves.easeInOutCubic));
|
||||||
|
|
||||||
|
return ClipRect(
|
||||||
|
child: SlideTransition(
|
||||||
|
position: slideAnimation,
|
||||||
|
child: FadeTransition(
|
||||||
|
opacity: animation,
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: selectedIndex == 1
|
||||||
|
? _buildListContent(key: const ValueKey('list'))
|
||||||
|
: const CustomMap(key: ValueKey('map')),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
// ElevatedButton(
|
|
||||||
// onPressed: () => showGPSDialog(context),
|
|
||||||
// child: Text("Test GPS Dialog"),
|
|
||||||
// )
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -179,50 +218,46 @@ class _NearbyState extends State<Nearby> {
|
||||||
Positioned(
|
Positioned(
|
||||||
left: 0,
|
left: 0,
|
||||||
child: _buildToggleButton(
|
child: _buildToggleButton(
|
||||||
color:
|
color: selectedIndex == 1
|
||||||
selectedIndex == 1
|
|
||||||
? const Color.fromARGB(255, 10, 69, 117)
|
? const Color.fromARGB(255, 10, 69, 117)
|
||||||
: const Color.fromARGB(100, 177, 177, 177),
|
: const Color.fromARGB(100, 177, 177, 177),
|
||||||
icon: Assets.icons.elementEqual.path,
|
icon: Assets.icons.elementEqual.path,
|
||||||
iconColor:
|
iconColor: selectedIndex == 1
|
||||||
selectedIndex == 1
|
|
||||||
? const Color.fromARGB(255, 234, 245, 254)
|
? const Color.fromARGB(255, 234, 245, 254)
|
||||||
: const Color.fromARGB(255, 157, 157, 155),
|
: const Color.fromARGB(255, 157, 157, 155),
|
||||||
text: 'list',
|
text: 'list',
|
||||||
isSelected: selectedIndex == 1,
|
isSelected: selectedIndex == 1,
|
||||||
onTap: () => setState(() => selectedIndex = 1),
|
onTap: () => _onToggle(1),
|
||||||
borderRadius: BorderRadius.only(
|
borderRadius: BorderRadius.only(
|
||||||
topLeft: Radius.circular(12),
|
topLeft: const Radius.circular(12),
|
||||||
bottomLeft: Radius.circular(12),
|
bottomLeft: const Radius.circular(12),
|
||||||
topRight:
|
topRight:
|
||||||
selectedIndex == 1 ? Radius.circular(12) : Radius.zero,
|
selectedIndex == 1 ? const Radius.circular(12) : Radius.zero,
|
||||||
bottomRight:
|
bottomRight:
|
||||||
selectedIndex == 1 ? Radius.circular(12) : Radius.zero,
|
selectedIndex == 1 ? const Radius.circular(12) : Radius.zero,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Positioned(
|
Positioned(
|
||||||
right: 0,
|
right: 0,
|
||||||
child: _buildToggleButton(
|
child: _buildToggleButton(
|
||||||
color:
|
color: selectedIndex == 0
|
||||||
selectedIndex == 0
|
|
||||||
? const Color.fromARGB(255, 10, 69, 117)
|
? const Color.fromARGB(255, 10, 69, 117)
|
||||||
: const Color.fromARGB(100, 177, 177, 177),
|
: const Color.fromARGB(100, 177, 177, 177),
|
||||||
iconColor:
|
iconColor: selectedIndex == 0
|
||||||
selectedIndex == 0
|
|
||||||
? const Color.fromARGB(255, 234, 245, 254)
|
? const Color.fromARGB(255, 234, 245, 254)
|
||||||
: const Color.fromARGB(255, 157, 157, 155),
|
: const Color.fromARGB(255, 157, 157, 155),
|
||||||
icon: Assets.icons.mapSelected.path,
|
icon: Assets.icons.mapSelected.path,
|
||||||
text: 'map',
|
text: 'map',
|
||||||
isSelected: selectedIndex == 0,
|
isSelected: selectedIndex == 0,
|
||||||
onTap: () => setState(() => selectedIndex = 0),
|
onTap: () => _onToggle(0),
|
||||||
borderRadius: BorderRadius.only(
|
borderRadius: BorderRadius.only(
|
||||||
topRight: Radius.circular(12),
|
topRight: const Radius.circular(12),
|
||||||
bottomRight: Radius.circular(12),
|
bottomRight: const Radius.circular(12),
|
||||||
bottomLeft:
|
bottomLeft:
|
||||||
selectedIndex == 0 ? Radius.circular(12) : Radius.zero,
|
selectedIndex == 0 ? const Radius.circular(12) : Radius.zero,
|
||||||
topLeft:
|
topLeft:
|
||||||
selectedIndex == 0 ? Radius.circular(12) : Radius.zero,
|
selectedIndex == 0 ? const Radius.circular(12) : Radius.zero,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -232,8 +267,32 @@ class _NearbyState extends State<Nearby> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildListContent() {
|
Widget _buildListContent({Key? key}) {
|
||||||
|
final listItems = [
|
||||||
|
ListScreen(
|
||||||
|
delivery: true,
|
||||||
|
pickup: false,
|
||||||
|
expiryTimeString: "2025-05-19T13:30:49.623619357Z",
|
||||||
|
ontap: () {
|
||||||
|
Navigator.of(context).push(
|
||||||
|
MaterialPageRoute(builder: (context) => const Productdetail()),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ListScreen(
|
||||||
|
delivery: false,
|
||||||
|
pickup: true,
|
||||||
|
expiryTimeString: "2025-05-25T05:20:49.623619357Z",
|
||||||
|
),
|
||||||
|
ListScreen(
|
||||||
|
delivery: true,
|
||||||
|
pickup: true,
|
||||||
|
expiryTimeString: "2025-05-12T13:20:37.435249520Z",
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
return SingleChildScrollView(
|
return SingleChildScrollView(
|
||||||
|
key: key,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(30, 5, 30, 0),
|
padding: const EdgeInsets.fromLTRB(30, 5, 30, 0),
|
||||||
child: Column(
|
child: Column(
|
||||||
|
|
@ -252,8 +311,7 @@ class _NearbyState extends State<Nearby> {
|
||||||
child: SvgPicture.asset(Assets.icons.arrowDown.path),
|
child: SvgPicture.asset(Assets.icons.arrowDown.path),
|
||||||
),
|
),
|
||||||
elevation: 16,
|
elevation: 16,
|
||||||
dropdownColor:
|
dropdownColor: Colors.white,
|
||||||
Colors.white,
|
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
color: Color.fromARGB(255, 33, 150, 243),
|
color: Color.fromARGB(255, 33, 150, 243),
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
|
|
@ -275,26 +333,33 @@ class _NearbyState extends State<Nearby> {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
ListScreen(
|
ListView.builder(
|
||||||
delivery: true,
|
shrinkWrap: true,
|
||||||
pickup: false,
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
expiryTimeString: "2025-05-19T13:30:49.623619357Z",
|
itemCount: listItems.length,
|
||||||
ontap: () {
|
itemBuilder: (context, index) {
|
||||||
Navigator.of(context).push(
|
final animation = Tween<double>(begin: 0.0, end: 1.0).animate(
|
||||||
MaterialPageRoute(builder: (context) => Productdetail()),
|
CurvedAnimation(
|
||||||
|
parent: _listAnimationController,
|
||||||
|
curve: Interval(
|
||||||
|
(0.1 * index),
|
||||||
|
(0.5 + 0.1 * index).clamp(0.0, 1.0),
|
||||||
|
curve: Curves.easeOutCubic,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return FadeTransition(
|
||||||
|
opacity: animation,
|
||||||
|
child: SlideTransition(
|
||||||
|
position: Tween<Offset>(
|
||||||
|
begin: const Offset(0, 0.5),
|
||||||
|
end: Offset.zero,
|
||||||
|
).animate(animation),
|
||||||
|
child: listItems[index],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
ListScreen(
|
|
||||||
delivery: false,
|
|
||||||
pickup: true,
|
|
||||||
expiryTimeString: "2025-05-25T05:20:49.623619357Z",
|
|
||||||
),
|
|
||||||
ListScreen(
|
|
||||||
delivery: true,
|
|
||||||
pickup: true,
|
|
||||||
expiryTimeString: "2025-05-12T13:20:37.435249520Z",
|
|
||||||
),
|
|
||||||
const SizedBox(height: 90),
|
const SizedBox(height: 90),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -320,12 +385,10 @@ class _NearbyState extends State<Nearby> {
|
||||||
height: 50,
|
height: 50,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: borderRadius,
|
borderRadius: borderRadius,
|
||||||
color:
|
color: isSelected
|
||||||
isSelected
|
|
||||||
? const Color.fromARGB(255, 14, 63, 102)
|
? const Color.fromARGB(255, 14, 63, 102)
|
||||||
: const Color.fromARGB(255, 234, 234, 233),
|
: const Color.fromARGB(255, 234, 234, 233),
|
||||||
boxShadow:
|
boxShadow: isSelected
|
||||||
isSelected
|
|
||||||
? [
|
? [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: Colors.black.withOpacity(0.2),
|
color: Colors.black.withOpacity(0.2),
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,9 @@ class _ItemState extends State<Item> with TickerProviderStateMixin {
|
||||||
bool showAllReviews = false;
|
bool showAllReviews = false;
|
||||||
final GlobalKey<AnimatedListState> _listKey = GlobalKey<AnimatedListState>();
|
final GlobalKey<AnimatedListState> _listKey = GlobalKey<AnimatedListState>();
|
||||||
|
|
||||||
|
late AnimationController _staggeredController;
|
||||||
|
late List<Animation<double>> _staggeredAnimations;
|
||||||
|
|
||||||
final List<Map<String, dynamic>> reviews = [
|
final List<Map<String, dynamic>> reviews = [
|
||||||
{
|
{
|
||||||
"name": "Sara M",
|
"name": "Sara M",
|
||||||
|
|
@ -80,6 +83,34 @@ class _ItemState extends State<Item> with TickerProviderStateMixin {
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
displayedReviews = reviews.length > 2 ? reviews.sublist(0, 2) : List.from(reviews);
|
displayedReviews = reviews.length > 2 ? reviews.sublist(0, 2) : List.from(reviews);
|
||||||
|
|
||||||
|
_staggeredController = AnimationController(
|
||||||
|
vsync: this,
|
||||||
|
duration: const Duration(milliseconds: 1200),
|
||||||
|
);
|
||||||
|
|
||||||
|
// --- FIX: Changed itemCount from 7 to 8 ---
|
||||||
|
final int itemCount = 8;
|
||||||
|
_staggeredAnimations = List.generate(itemCount, (index) {
|
||||||
|
return Tween<double>(begin: 0.0, end: 1.0).animate(
|
||||||
|
CurvedAnimation(
|
||||||
|
parent: _staggeredController,
|
||||||
|
curve: Interval(
|
||||||
|
(0.1 * index),
|
||||||
|
(0.5 + 0.1 * index).clamp(0.0, 1.0),
|
||||||
|
curve: Curves.easeOutCubic,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
_staggeredController.forward();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_staggeredController.dispose();
|
||||||
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showAllReviewsWithAnimation() async {
|
void _showAllReviewsWithAnimation() async {
|
||||||
|
|
@ -95,6 +126,19 @@ class _ItemState extends State<Item> with TickerProviderStateMixin {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildAnimatedWidget(Widget child, int index) {
|
||||||
|
return FadeTransition(
|
||||||
|
opacity: _staggeredAnimations[index],
|
||||||
|
child: SlideTransition(
|
||||||
|
position: Tween<Offset>(
|
||||||
|
begin: const Offset(0.0, 0.3),
|
||||||
|
end: Offset.zero,
|
||||||
|
).animate(_staggeredAnimations[index]),
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Padding(
|
return Padding(
|
||||||
|
|
@ -103,6 +147,7 @@ class _ItemState extends State<Item> with TickerProviderStateMixin {
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
|
_buildAnimatedWidget(
|
||||||
Align(
|
Align(
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
child: Text(
|
child: Text(
|
||||||
|
|
@ -110,7 +155,10 @@ class _ItemState extends State<Item> with TickerProviderStateMixin {
|
||||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
|
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
0,
|
||||||
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
|
_buildAnimatedWidget(
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Text("Brand: "),
|
Text("Brand: "),
|
||||||
|
|
@ -123,7 +171,10 @@ class _ItemState extends State<Item> with TickerProviderStateMixin {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
1,
|
||||||
|
),
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
|
_buildAnimatedWidget(
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
CustomStarRating(rating: 4.8),
|
CustomStarRating(rating: 4.8),
|
||||||
|
|
@ -134,7 +185,10 @@ class _ItemState extends State<Item> with TickerProviderStateMixin {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
2,
|
||||||
|
),
|
||||||
SizedBox(height: 15),
|
SizedBox(height: 15),
|
||||||
|
_buildAnimatedWidget(
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
OrderType(
|
OrderType(
|
||||||
|
|
@ -150,11 +204,13 @@ class _ItemState extends State<Item> with TickerProviderStateMixin {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
3,
|
||||||
|
),
|
||||||
SizedBox(height: 15),
|
SizedBox(height: 15),
|
||||||
buildWrappedInfo("Dimensions:", widget.dimensions),
|
_buildAnimatedWidget(buildWrappedInfo("Dimensions:", widget.dimensions), 4),
|
||||||
buildWrappedInfo("Colour:", widget.colour),
|
_buildAnimatedWidget(buildWrappedInfo("Colour:", widget.colour), 5),
|
||||||
buildWrappedInfo("Material:", widget.material),
|
_buildAnimatedWidget(buildWrappedInfo("Material:", widget.material), 6),
|
||||||
buildWrappedInfo("Description:", widget.description),
|
_buildAnimatedWidget(buildWrappedInfo("Description:", widget.description), 7), // Now this is valid
|
||||||
SizedBox(height: 30),
|
SizedBox(height: 30),
|
||||||
Center(
|
Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
|
|
@ -171,7 +227,12 @@ class _ItemState extends State<Item> with TickerProviderStateMixin {
|
||||||
initialItemCount: displayedReviews.length,
|
initialItemCount: displayedReviews.length,
|
||||||
itemBuilder: (context, index, animation) {
|
itemBuilder: (context, index, animation) {
|
||||||
final review = displayedReviews[index];
|
final review = displayedReviews[index];
|
||||||
return SizeTransition(
|
return SlideTransition(
|
||||||
|
position: Tween<Offset>(
|
||||||
|
begin: const Offset(-1, 0),
|
||||||
|
end: Offset.zero,
|
||||||
|
).animate(CurvedAnimation(parent: animation, curve: Curves.easeInOut)),
|
||||||
|
child: SizeTransition(
|
||||||
sizeFactor: animation,
|
sizeFactor: animation,
|
||||||
axisAlignment: -1,
|
axisAlignment: -1,
|
||||||
child: Reviews(
|
child: Reviews(
|
||||||
|
|
@ -182,6 +243,7 @@ class _ItemState extends State<Item> with TickerProviderStateMixin {
|
||||||
noCount: review['noCount'],
|
noCount: review['noCount'],
|
||||||
date: review['date'],
|
date: review['date'],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
// ignore_for_file: deprecated_member_use
|
|
||||||
|
|
||||||
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/data/model/workingHours.dart';
|
import 'package:lba/data/model/workingHours.dart';
|
||||||
|
|
|
||||||
|
|
@ -33,15 +33,58 @@ class Shop extends StatefulWidget {
|
||||||
State<Shop> createState() => _ShopState();
|
State<Shop> createState() => _ShopState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ShopState extends State<Shop> {
|
class _ShopState extends State<Shop> with TickerProviderStateMixin {
|
||||||
late String selectedPlace;
|
late String selectedPlace;
|
||||||
bool isActiveOffer = true;
|
bool isActiveOffer = true;
|
||||||
|
|
||||||
|
late AnimationController _staggeredController;
|
||||||
|
late List<Animation<double>> _staggeredAnimations;
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
selectedPlace = widget.place;
|
selectedPlace = widget.place;
|
||||||
|
|
||||||
|
_staggeredController = AnimationController(
|
||||||
|
vsync: this,
|
||||||
|
duration: const Duration(milliseconds: 1200),
|
||||||
|
);
|
||||||
|
|
||||||
|
final int itemCount = 8;
|
||||||
|
_staggeredAnimations = List.generate(itemCount, (index) {
|
||||||
|
return Tween<double>(begin: 0.0, end: 1.0).animate(
|
||||||
|
CurvedAnimation(
|
||||||
|
parent: _staggeredController,
|
||||||
|
curve: Interval(
|
||||||
|
(0.1 * index),
|
||||||
|
(0.5 + 0.1 * index).clamp(0.0, 1.0),
|
||||||
|
curve: Curves.easeOutCubic,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
_staggeredController.forward();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_staggeredController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildAnimatedWidget(Widget child, int index) {
|
||||||
|
return FadeTransition(
|
||||||
|
opacity: _staggeredAnimations[index],
|
||||||
|
child: SlideTransition(
|
||||||
|
position: Tween<Offset>(
|
||||||
|
begin: const Offset(0.0, 0.5),
|
||||||
|
end: Offset.zero,
|
||||||
|
).animate(_staggeredAnimations[index]),
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -64,6 +107,7 @@ class _ShopState extends State<Shop> {
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
|
_buildAnimatedWidget(
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.asset(
|
||||||
|
|
@ -78,7 +122,10 @@ class _ShopState extends State<Shop> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
0,
|
||||||
|
),
|
||||||
SizedBox(height: 15),
|
SizedBox(height: 15),
|
||||||
|
_buildAnimatedWidget(
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
CustomStarRating(rating: widget.star),
|
CustomStarRating(rating: widget.star),
|
||||||
|
|
@ -89,7 +136,10 @@ class _ShopState extends State<Shop> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
1,
|
||||||
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
|
_buildAnimatedWidget(
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -131,7 +181,10 @@ class _ShopState extends State<Shop> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
2,
|
||||||
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
|
_buildAnimatedWidget(
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(Assets.icons.clock.path),
|
SvgPicture.asset(Assets.icons.clock.path),
|
||||||
|
|
@ -153,8 +206,11 @@ class _ShopState extends State<Shop> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
3,
|
||||||
|
),
|
||||||
SizedBox(height: 15),
|
SizedBox(height: 15),
|
||||||
DividerTitleWidget(title: "Facilities"),
|
_buildAnimatedWidget(DividerTitleWidget(title: "Facilities"), 4),
|
||||||
|
_buildAnimatedWidget(
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 50,
|
height: 50,
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
|
|
@ -176,7 +232,10 @@ class _ShopState extends State<Shop> {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
5,
|
||||||
|
),
|
||||||
SizedBox(height: 20),
|
SizedBox(height: 20),
|
||||||
|
_buildAnimatedWidget(
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor: LightAppColors.confirmButton,
|
backgroundColor: LightAppColors.confirmButton,
|
||||||
|
|
@ -206,7 +265,10 @@ class _ShopState extends State<Shop> {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
6,
|
||||||
|
),
|
||||||
SizedBox(height: 30),
|
SizedBox(height: 30),
|
||||||
|
_buildAnimatedWidget(
|
||||||
Text(
|
Text(
|
||||||
"List of offers",
|
"List of offers",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
|
|
@ -214,6 +276,8 @@ class _ShopState extends State<Shop> {
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
7,
|
||||||
|
),
|
||||||
SizedBox(height: 15),
|
SizedBox(height: 15),
|
||||||
Container(
|
Container(
|
||||||
height: 45,
|
height: 45,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,174 @@
|
||||||
|
import 'dart:math';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import '../gen/assets.gen.dart';
|
||||||
|
|
||||||
|
class CoolSplashScreen extends StatefulWidget {
|
||||||
|
final Widget nextScreen;
|
||||||
|
final Duration duration;
|
||||||
|
|
||||||
|
const CoolSplashScreen({
|
||||||
|
super.key,
|
||||||
|
required this.nextScreen,
|
||||||
|
this.duration = const Duration(seconds: 6),
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<CoolSplashScreen> createState() => _CoolSplashScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CoolSplashScreenState extends State<CoolSplashScreen>
|
||||||
|
with TickerProviderStateMixin {
|
||||||
|
late AnimationController _mainController;
|
||||||
|
late Animation<double> _backgroundAnimation;
|
||||||
|
late Animation<double> _particlesAnimation;
|
||||||
|
late Animation<double> _logoAnimation;
|
||||||
|
late Animation<double> _textAnimation;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
_mainController = AnimationController(
|
||||||
|
duration: const Duration(milliseconds: 4000),
|
||||||
|
vsync: this,
|
||||||
|
);
|
||||||
|
|
||||||
|
_backgroundAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
|
||||||
|
CurvedAnimation(
|
||||||
|
parent: _mainController,
|
||||||
|
curve: const Interval(0.0, 0.5, curve: Curves.easeInOut),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
_particlesAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
|
||||||
|
CurvedAnimation(
|
||||||
|
parent: _mainController,
|
||||||
|
curve: const Interval(0.2, 0.7, curve: Curves.easeOut),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
_logoAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
|
||||||
|
CurvedAnimation(
|
||||||
|
parent: _mainController,
|
||||||
|
curve: const Interval(0.5, 0.9, curve: Curves.elasticOut),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
_textAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
|
||||||
|
CurvedAnimation(
|
||||||
|
parent: _mainController,
|
||||||
|
curve: const Interval(0.7, 1.0, curve: Curves.easeOut),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
_mainController.forward();
|
||||||
|
|
||||||
|
Future.delayed(widget.duration, () {
|
||||||
|
if (mounted) {
|
||||||
|
Navigator.of(context).pushReplacement(
|
||||||
|
PageRouteBuilder(
|
||||||
|
pageBuilder: (_, __, ___) => widget.nextScreen,
|
||||||
|
transitionDuration: const Duration(milliseconds: 700),
|
||||||
|
transitionsBuilder: (_, animation, __, child) {
|
||||||
|
return FadeTransition(opacity: animation, child: child);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_mainController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body: AnimatedBuilder(
|
||||||
|
animation: _mainController,
|
||||||
|
builder: (context, child) {
|
||||||
|
return Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
|
colors: [
|
||||||
|
Color.lerp(const Color(0xFFF5F5F5), const Color(0xFFE0E0E0), _backgroundAnimation.value)!,
|
||||||
|
Color.lerp(const Color(0xFFFFFFFF), const Color(0xFFF5F5F5), _backgroundAnimation.value)!,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
for (int i = 0; i < 30; i++)
|
||||||
|
Particle(
|
||||||
|
animation: _particlesAnimation,
|
||||||
|
size: Random().nextDouble() * 5 + 2,
|
||||||
|
color: Colors.blueGrey.withOpacity(Random().nextDouble() * 0.3 + 0.1),
|
||||||
|
alignment: Alignment(
|
||||||
|
(Random().nextDouble() * 2 - 1) * (2 - _particlesAnimation.value),
|
||||||
|
(Random().nextDouble() * 2 - 1) * (2 - _particlesAnimation.value),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Transform.scale(
|
||||||
|
scale: _logoAnimation.value,
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
Assets.images.logo.path,
|
||||||
|
height: 140,
|
||||||
|
width: 140,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 30),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Particle extends StatelessWidget {
|
||||||
|
final Animation<double> animation;
|
||||||
|
final double size;
|
||||||
|
final Color color;
|
||||||
|
final Alignment alignment;
|
||||||
|
|
||||||
|
const Particle({
|
||||||
|
super.key,
|
||||||
|
required this.animation,
|
||||||
|
required this.size,
|
||||||
|
required this.color,
|
||||||
|
required this.alignment,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Align(
|
||||||
|
alignment: alignment,
|
||||||
|
child: Opacity(
|
||||||
|
opacity: animation.value,
|
||||||
|
child: Container(
|
||||||
|
width: size,
|
||||||
|
height: size,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: color,
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,7 +6,6 @@ import 'package:geolocator/geolocator.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';
|
||||||
|
|
||||||
|
|
||||||
Future<void> showGPSDialog(BuildContext context) async {
|
Future<void> showGPSDialog(BuildContext context) async {
|
||||||
bool isLocationEnabled = await Geolocator.isLocationServiceEnabled();
|
bool isLocationEnabled = await Geolocator.isLocationServiceEnabled();
|
||||||
if (!isLocationEnabled) {
|
if (!isLocationEnabled) {
|
||||||
|
|
@ -14,8 +13,61 @@ Future<void> showGPSDialog(BuildContext context) async {
|
||||||
context: context,
|
context: context,
|
||||||
barrierDismissible: false,
|
barrierDismissible: false,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return Dialog(
|
return const _AnimatedGpsDialog();
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AnimatedGpsDialog extends StatefulWidget {
|
||||||
|
const _AnimatedGpsDialog({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<_AnimatedGpsDialog> createState() => _AnimatedGpsDialogState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AnimatedGpsDialogState extends State<_AnimatedGpsDialog>
|
||||||
|
with SingleTickerProviderStateMixin {
|
||||||
|
late AnimationController _controller;
|
||||||
|
late Animation<double> _scaleAnimation;
|
||||||
|
late Animation<double> _fadeAnimation;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_controller = AnimationController(
|
||||||
|
vsync: this,
|
||||||
|
duration: const Duration(milliseconds: 450),
|
||||||
|
);
|
||||||
|
|
||||||
|
_scaleAnimation = CurvedAnimation(
|
||||||
|
parent: _controller,
|
||||||
|
curve: Curves.elasticOut,
|
||||||
|
);
|
||||||
|
|
||||||
|
_fadeAnimation = CurvedAnimation(
|
||||||
|
parent: _controller,
|
||||||
|
curve: Curves.easeIn,
|
||||||
|
);
|
||||||
|
|
||||||
|
_controller.forward();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_controller.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return FadeTransition(
|
||||||
|
opacity: _fadeAnimation,
|
||||||
|
child: ScaleTransition(
|
||||||
|
scale: _scaleAnimation,
|
||||||
|
child: Dialog(
|
||||||
|
shape:
|
||||||
|
RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
|
||||||
elevation: 10,
|
elevation: 10,
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
|
|
@ -23,14 +75,15 @@ Future<void> showGPSDialog(BuildContext context) async {
|
||||||
alignment: Alignment.topCenter,
|
alignment: Alignment.topCenter,
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(top: 40, left: 20, right: 20, bottom: 20),
|
padding: const EdgeInsets.only(
|
||||||
|
top: 40, left: 20, right: 20, bottom: 20),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
Padding(
|
const Padding(
|
||||||
padding: const EdgeInsets.all(15.0),
|
padding: EdgeInsets.all(15.0),
|
||||||
child: const Text(
|
child: Text(
|
||||||
"Enable Location",
|
"Enable Location",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
|
|
@ -60,11 +113,11 @@ Future<void> showGPSDialog(BuildContext context) async {
|
||||||
foregroundColor: Colors.black,
|
foregroundColor: Colors.black,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
side: BorderSide(color: Colors.grey),
|
side: const BorderSide(color: Colors.grey),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
child: Text("Not now"),
|
child: const Text("Not now"),
|
||||||
),
|
),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
|
|
@ -72,9 +125,11 @@ Future<void> showGPSDialog(BuildContext context) async {
|
||||||
foregroundColor: Colors.black,
|
foregroundColor: Colors.black,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
side: BorderSide(color: LightAppColors.inputBorder),
|
side: BorderSide(
|
||||||
|
color: LightAppColors.inputBorder),
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 35, vertical: 7),
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 35, vertical: 7),
|
||||||
),
|
),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await Geolocator.openLocationSettings();
|
await Geolocator.openLocationSettings();
|
||||||
|
|
@ -99,7 +154,7 @@ Future<void> showGPSDialog(BuildContext context) async {
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: Colors.black.withOpacity(0.3),
|
color: Colors.black.withOpacity(0.3),
|
||||||
blurRadius: 8,
|
blurRadius: 8,
|
||||||
offset: Offset(0, 4),
|
offset: const Offset(0, 4),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -108,15 +163,16 @@ Future<void> showGPSDialog(BuildContext context) async {
|
||||||
radius: 40,
|
radius: 40,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(12.0),
|
padding: const EdgeInsets.all(12.0),
|
||||||
child: SvgPicture.asset(Assets.icons.fluentColorLocationRipple16.path),
|
child: SvgPicture.asset(
|
||||||
|
Assets.icons.fluentColorLocationRipple16.path),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
},
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:lba/gen/assets.gen.dart';
|
||||||
|
|
||||||
|
class SearchBarWidget extends StatelessWidget {
|
||||||
|
const SearchBarWidget({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 15),
|
||||||
|
child: SizedBox(
|
||||||
|
height: 50,
|
||||||
|
child: TextField(
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: 'What are you looking for?',
|
||||||
|
hintStyle: const TextStyle(
|
||||||
|
color: Colors.grey,
|
||||||
|
fontSize: 13,
|
||||||
|
),
|
||||||
|
prefixIcon: Padding(
|
||||||
|
padding: const EdgeInsets.all(10.0),
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
Assets.icons.riSearch2Line.path,
|
||||||
|
width: 18,
|
||||||
|
height: 18,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
filled: true,
|
||||||
|
fillColor: const Color.fromARGB(255, 248, 248, 248),
|
||||||
|
contentPadding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 16.0,
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
borderSide: const BorderSide(
|
||||||
|
color: Color.fromARGB(255, 14, 63, 102),
|
||||||
|
width: 2.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
borderSide: const BorderSide(
|
||||||
|
color: Color.fromARGB(255, 14, 63, 102),
|
||||||
|
width: 1.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -241,6 +241,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.1.1"
|
||||||
|
dots_indicator:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: dots_indicator
|
||||||
|
sha256: c070af5058a084ba7b354df4b4c26c719595d70a3531eea6edd8af8716684ba3
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.0.1"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ dependencies:
|
||||||
latlong2: ^0.9.1
|
latlong2: ^0.9.1
|
||||||
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
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue