diff --git a/assets/fonts/Baloo2-Bold.ttf b/assets/fonts/Baloo2-Bold.ttf new file mode 100644 index 0000000..c2f6f69 Binary files /dev/null and b/assets/fonts/Baloo2-Bold.ttf differ diff --git a/assets/fonts/Baloo2-ExtraBold.ttf b/assets/fonts/Baloo2-ExtraBold.ttf new file mode 100644 index 0000000..58286dd Binary files /dev/null and b/assets/fonts/Baloo2-ExtraBold.ttf differ diff --git a/assets/fonts/Baloo2-Medium.ttf b/assets/fonts/Baloo2-Medium.ttf new file mode 100644 index 0000000..32cf92d Binary files /dev/null and b/assets/fonts/Baloo2-Medium.ttf differ diff --git a/assets/fonts/Baloo2-SemiBold.ttf b/assets/fonts/Baloo2-SemiBold.ttf new file mode 100644 index 0000000..eb39dd1 Binary files /dev/null and b/assets/fonts/Baloo2-SemiBold.ttf differ diff --git a/assets/fonts/dinokids.ttf b/assets/fonts/DinoKids-Regular.ttf similarity index 100% rename from assets/fonts/dinokids.ttf rename to assets/fonts/DinoKids-Regular.ttf diff --git a/assets/fonts/Marhey-Light.ttf b/assets/fonts/Marhey-Light.ttf deleted file mode 100644 index edb49bd..0000000 Binary files a/assets/fonts/Marhey-Light.ttf and /dev/null differ diff --git a/assets/fonts/Marhey-Medium.ttf b/assets/fonts/Marhey-Medium.ttf deleted file mode 100644 index 1a5b780..0000000 Binary files a/assets/fonts/Marhey-Medium.ttf and /dev/null differ diff --git a/assets/fonts/Marhey-Regular.ttf b/assets/fonts/Marhey-Regular.ttf deleted file mode 100644 index 6ac4483..0000000 Binary files a/assets/fonts/Marhey-Regular.ttf and /dev/null differ diff --git a/assets/images/intro_1.jpg b/assets/images/intro_1.jpg new file mode 100644 index 0000000..2737fcf Binary files /dev/null and b/assets/images/intro_1.jpg differ diff --git a/assets/images/intro_2.jpg b/assets/images/intro_2.jpg new file mode 100644 index 0000000..d5d4f9c Binary files /dev/null and b/assets/images/intro_2.jpg differ diff --git a/assets/images/intro_3.jpg b/assets/images/intro_3.jpg new file mode 100644 index 0000000..83afd24 Binary files /dev/null and b/assets/images/intro_3.jpg differ diff --git a/assets/images/intro_4.jpg b/assets/images/intro_4.jpg new file mode 100644 index 0000000..9b7795c Binary files /dev/null and b/assets/images/intro_4.jpg differ diff --git a/assets/images/intro_5.jpg b/assets/images/intro_5.jpg new file mode 100644 index 0000000..62209ed Binary files /dev/null and b/assets/images/intro_5.jpg differ diff --git a/lib/common_ui/resources/my_assets.dart b/lib/common_ui/resources/my_assets.dart index 7fbb1e5..27dc537 100644 --- a/lib/common_ui/resources/my_assets.dart +++ b/lib/common_ui/resources/my_assets.dart @@ -22,6 +22,11 @@ class MyAssets { static const String ship = 'assets/images/ship.png'; static const String shiny = 'assets/images/shiny.png'; static const String loading = 'assets/images/loading.png'; + static const String intro_1 = 'assets/images/intro_1.jpg'; + static const String intro_2 = 'assets/images/intro_2.jpg'; + static const String intro_3 = 'assets/images/intro_3.jpg'; + static const String intro_4 = 'assets/images/intro_4.jpg'; + static const String intro_5 = 'assets/images/intro_5.jpg'; /// SVG static const String closeBtn = 'assets/svg/close_btn.svg'; @@ -71,5 +76,10 @@ class MyAssets { ship, shiny, loading, + intro_1, + intro_2, + intro_3, + intro_4, + intro_5, ]; } \ No newline at end of file diff --git a/lib/common_ui/resources/my_text_style.dart b/lib/common_ui/resources/my_text_style.dart index c8d64c9..adf33c2 100644 --- a/lib/common_ui/resources/my_text_style.dart +++ b/lib/common_ui/resources/my_text_style.dart @@ -1,11 +1,12 @@ import 'package:flutter/material.dart'; +import 'package:hadi_hoda_flutter/common_ui/resources/my_colors.dart'; class DinoKids { static const DinoKids _i = DinoKids._internal(); const DinoKids._internal(); factory DinoKids() => _i; - static const String fontFamily = 'dinokids'; + static const String fontFamily = 'DinoKids'; /// Regular static const TextStyle regular17 = TextStyle( @@ -33,6 +34,11 @@ class DinoKids { fontSize: 45, fontWeight: FontWeight.w400, ); + + static const TextStyle regular = TextStyle( + fontFamily: fontFamily, + fontWeight: FontWeight.w400, + ); } class Marhey { @@ -40,7 +46,7 @@ class Marhey { const Marhey._internal(); factory Marhey() => _i; - static const String fontFamily = 'marhey'; + static const String fontFamily = 'Marhey'; /// Medium static const TextStyle medium12 = TextStyle( @@ -97,4 +103,131 @@ class Marhey { fontSize: 26, fontWeight: FontWeight.w700, ); + + static const TextStyle semiBold = TextStyle( + fontFamily: fontFamily, + fontWeight: FontWeight.w600, + ); + + static const TextStyle bold = TextStyle( + fontFamily: fontFamily, + fontWeight: FontWeight.w700, + ); } + +class Baloo2 { + static const Baloo2 _i = Baloo2._internal(); + const Baloo2._internal(); + factory Baloo2() => _i; + + static const String fontFamily = 'Baloo_2'; + + static const TextStyle medium = TextStyle( + fontFamily: fontFamily, + fontWeight: FontWeight.w500, + ); + + static const TextStyle semiBold = TextStyle( + fontFamily: fontFamily, + fontWeight: FontWeight.w600, + ); + + static const TextStyle bold = TextStyle( + fontFamily: fontFamily, + fontWeight: FontWeight.w700, + ); + + static const TextStyle extraBold = TextStyle( + fontFamily: fontFamily, + fontWeight: FontWeight.w800, + ); +} + + +class MYTextStyle { + static const MYTextStyle _i = MYTextStyle._internal(); + const MYTextStyle._internal(); + factory MYTextStyle() => _i; + + static const String dinoKids = 'DinoKids'; + static const String marhey = 'Marhey'; + static const String baloo2 = 'Baloo_2'; + static const Color textColor = MyColors.white; + + static const TextStyle titr0 = TextStyle( + fontFamily: marhey, + fontWeight: FontWeight.w700, + fontSize: 26, + color: textColor, + ); + + static const TextStyle titr1 = TextStyle( + fontFamily: baloo2, + fontWeight: FontWeight.w800, + fontSize: 20, + color: textColor, + ); + + static const TextStyle titr3 = TextStyle( + fontFamily: marhey, + fontWeight: FontWeight.w600, + fontSize: 18, + color: textColor, + ); + + static const TextStyle titr4 = TextStyle( + fontFamily: baloo2, + fontWeight: FontWeight.w700, + fontSize: 14, + color: textColor, + ); + + static const TextStyle matn1 = TextStyle( + fontFamily: baloo2, + fontWeight: FontWeight.w600, + fontSize: 18, + color: textColor, + ); + + static const TextStyle matn2_3 = TextStyle( + fontFamily: baloo2, + fontWeight: FontWeight.w700, + fontSize: 18, + color: textColor, + ); + + static const TextStyle matn2_2 = TextStyle( + fontFamily: baloo2, + fontWeight: FontWeight.w700, + fontSize: 16, + color: textColor, + ); + + static const TextStyle matn2 = TextStyle( + fontFamily: baloo2, + fontWeight: FontWeight.w700, + fontSize: 14, + color: textColor, + ); + + static const TextStyle matn3 = TextStyle( + fontFamily: baloo2, + fontWeight: FontWeight.w500, + fontSize: 12, + color: textColor, + ); + + static const TextStyle button1 = TextStyle( + fontFamily: dinoKids, + fontWeight: FontWeight.w400, + fontSize: 45, + color: textColor, + ); + + static const TextStyle button2 = TextStyle( + fontFamily: dinoKids, + fontWeight: FontWeight.w400, + fontSize: 30, + color: textColor, + ); +} \ No newline at end of file diff --git a/lib/common_ui/theme/my_theme.dart b/lib/common_ui/theme/my_theme.dart index c0f9552..d59c6b9 100644 --- a/lib/common_ui/theme/my_theme.dart +++ b/lib/common_ui/theme/my_theme.dart @@ -1,24 +1,10 @@ import 'package:flutter/material.dart'; -import 'package:hadi_hoda_flutter/common_ui/resources/my_colors.dart'; - -enum ColorsName { primaryColor, backgroundDialog } class MyTheme { static const MyTheme _i = MyTheme._internal(); const MyTheme._internal(); factory MyTheme() => _i; - static final ThemeData light = ThemeData(brightness: Brightness.dark); - - static final ThemeData dark = ThemeData(brightness: Brightness.light); - - static Map get lightColors => { - ColorsName.primaryColor: MyColors.white, - ColorsName.backgroundDialog: MyColors.purple, - }; - - static Map get darkColors => { - ColorsName.primaryColor: MyColors.black, - ColorsName.backgroundDialog: MyColors.purple, - }; + static final ThemeData light = ThemeData(brightness: Brightness.light); + static final ThemeData dark = ThemeData(brightness: Brightness.dark); } \ No newline at end of file diff --git a/lib/core/routers/my_routes.dart b/lib/core/routers/my_routes.dart index bbc3589..92ad404 100644 --- a/lib/core/routers/my_routes.dart +++ b/lib/core/routers/my_routes.dart @@ -40,7 +40,7 @@ class Routes { } GoRouter get appPages => GoRouter( - initialLocation: Routes.introPage, + initialLocation: Routes.splashPage, navigatorKey: ContextProvider.navigatorKey, routes: [ GoRoute( diff --git a/lib/core/utils/my_device.dart b/lib/core/utils/my_device.dart index b2ad461..3bf919a 100644 --- a/lib/core/utils/my_device.dart +++ b/lib/core/utils/my_device.dart @@ -65,7 +65,6 @@ class MyDevice { await SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, ]); - } static Future setLandscape() async { @@ -83,4 +82,17 @@ class MyDevice { DeviceOrientation.portraitDown, ]); } + + /// Set System UI Mode + static Future setEdgeToEdge() async { + await SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); + } + + static Future setImmersiveSticky() async { + await SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky); + } + + static Future setImmersive() async { + await SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive); + } } diff --git a/lib/core/utils/screen_size.dart b/lib/core/utils/screen_size.dart index b4efd63..9778668 100644 --- a/lib/core/utils/screen_size.dart +++ b/lib/core/utils/screen_size.dart @@ -1,6 +1,13 @@ import 'package:flutter/material.dart'; +import 'package:hadi_hoda_flutter/core/utils/context_provider.dart'; extension ScreenSize on BuildContext { double get widthScreen => MediaQuery.sizeOf(this).width; double get heightScreen => MediaQuery.sizeOf(this).height; } + + +extension AdaptiveSize on double { + double get w => ContextProvider.context.widthScreen * this; + double get h => ContextProvider.context.heightScreen * this; +} diff --git a/lib/core/utils/check_platform.dart b/lib/core/utils/set_platform_size.dart similarity index 77% rename from lib/core/utils/check_platform.dart rename to lib/core/utils/set_platform_size.dart index 4b2fe90..78a1f45 100644 --- a/lib/core/utils/check_platform.dart +++ b/lib/core/utils/set_platform_size.dart @@ -1,10 +1,10 @@ import 'package:flutter/cupertino.dart'; import 'package:hadi_hoda_flutter/core/utils/my_device.dart'; -dynamic checkPlatform({ - dynamic android, - dynamic iOS, - dynamic web, +T? setPlatform({ + T? android, + T? iOS, + T? web, }) { if (MyDevice.isAndroid()) { return android; @@ -12,14 +12,16 @@ dynamic checkPlatform({ return iOS; } else if (MyDevice.isWeb()) { return web; + } else { + return null; } } -double? checkSize({ +T? setSize({ required BuildContext context, - double? mobile, - double? tablet, - double? desktop, + T? mobile, + T? tablet, + T? desktop, }) { if (MyDevice.isMobile(context)) { return mobile; diff --git a/lib/core/widgets/about_us_dialog/about_us_dialog.dart b/lib/core/widgets/about_us_dialog/about_us_dialog.dart index 5b44a9b..51c1db3 100644 --- a/lib/core/widgets/about_us_dialog/about_us_dialog.dart +++ b/lib/core/widgets/about_us_dialog/about_us_dialog.dart @@ -5,8 +5,8 @@ import 'package:go_router/go_router.dart'; import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart'; import 'package:hadi_hoda_flutter/common_ui/resources/my_colors.dart'; import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart'; -import 'package:hadi_hoda_flutter/core/utils/check_platform.dart'; import 'package:hadi_hoda_flutter/core/utils/my_localization.dart'; +import 'package:hadi_hoda_flutter/core/utils/set_platform_size.dart'; import 'package:hadi_hoda_flutter/core/widgets/about_us_dialog/styles/background.dart'; import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; @@ -31,7 +31,7 @@ class AboutUsDialog extends StatelessWidget { child: Center( child: Padding( padding: EdgeInsets.symmetric( - horizontal: checkSize( + horizontal: setSize( context: context, mobile: 18, tablet: 120, @@ -69,19 +69,19 @@ class AboutUsDialog extends StatelessWidget { children: [ MyImage( image: MyAssets.facebook, - size: checkSize(context: context, mobile: 33, tablet: 46), + size: setSize(context: context, mobile: 33, tablet: 46), ), MyImage( image: MyAssets.instagram, - size: checkSize(context: context, mobile: 33, tablet: 46), + size: setSize(context: context, mobile: 33, tablet: 46), ), MyImage( image: MyAssets.whatsapp, - size: checkSize(context: context, mobile: 33, tablet: 46), + size: setSize(context: context, mobile: 33, tablet: 46), ), MyImage( image: MyAssets.youtube, - size: checkSize(context: context, mobile: 33, tablet: 46), + size: setSize(context: context, mobile: 33, tablet: 46), ), ], ), @@ -89,14 +89,14 @@ class AboutUsDialog extends StatelessWidget { ), ), Positioned( - right: checkSize(context: context, mobile: 30, tablet: 40), + right: setSize(context: context, mobile: 30, tablet: 40), top: -12, child: GestureDetector( onTap: context.pop, behavior: HitTestBehavior.opaque, child: MyImage( image: MyAssets.closeBtn, - size: checkSize(context: context, mobile: 40, tablet: 60), + size: setSize(context: context, mobile: 40, tablet: 60), ), ), ), diff --git a/lib/core/widgets/about_us_dialog/styles/background.dart b/lib/core/widgets/about_us_dialog/styles/background.dart index 4a8b91d..45803d9 100644 --- a/lib/core/widgets/about_us_dialog/styles/background.dart +++ b/lib/core/widgets/about_us_dialog/styles/background.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:hadi_hoda_flutter/core/utils/check_platform.dart'; import 'package:hadi_hoda_flutter/core/utils/screen_size.dart'; +import 'package:hadi_hoda_flutter/core/utils/set_platform_size.dart'; class AboutUSDialogBackground extends StatelessWidget { const AboutUSDialogBackground({super.key, this.child}); @@ -13,9 +13,9 @@ class AboutUSDialogBackground extends StatelessWidget { clipper: _BottomShapeClipper(), child: Container( width: context.widthScreen, - height: checkSize(context: context, mobile: 525, tablet: 740), + height: setSize(context: context, mobile: 525, tablet: 740), padding: EdgeInsets.all( - checkSize( + setSize( context: context, mobile: 30, tablet: 60, diff --git a/lib/core/widgets/animations/slide_up_fade.dart b/lib/core/widgets/animations/slide_up_fade.dart new file mode 100644 index 0000000..5b9dda4 --- /dev/null +++ b/lib/core/widgets/animations/slide_up_fade.dart @@ -0,0 +1,67 @@ +import 'package:flutter/material.dart'; + +class SlideUpFade extends StatefulWidget { + const SlideUpFade({ + super.key, + required this.child, + this.delay = Duration.zero, + }); + + final Widget child; + final Duration delay; + + @override + State createState() => _SlideUpFadeState(); +} + +class _SlideUpFadeState extends State + with SingleTickerProviderStateMixin { + late AnimationController _controller; + late Animation _fadeAnim; + late Animation _slideAnim; + + @override + void initState() { + super.initState(); + _controller = AnimationController( + vsync: this, + duration: Duration(milliseconds: 500), + reverseDuration: Duration(milliseconds: 500), + ); + + _fadeAnim = Tween( + begin: 0, + end: 1, + ).animate(CurvedAnimation(parent: _controller, curve: Curves.easeIn)); + + _slideAnim = Tween( + begin: Offset(0, 0.1), + end: Offset.zero, + ).animate(CurvedAnimation(parent: _controller, curve: Curves.easeIn)); + startAnim(); + } + + Future startAnim() async { + await Future.delayed(widget.delay, () { + _controller.forward(); + }); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return AnimatedBuilder( + animation: _controller, + child: widget.child, + builder: (context, child) => FadeTransition( + opacity: _fadeAnim, + child: SlideTransition(position: _slideAnim, child: child), + ), + ); + } +} diff --git a/lib/core/widgets/hadith_dialog/hadith_dialog.dart b/lib/core/widgets/hadith_dialog/hadith_dialog.dart index 063a616..56d1257 100644 --- a/lib/core/widgets/hadith_dialog/hadith_dialog.dart +++ b/lib/core/widgets/hadith_dialog/hadith_dialog.dart @@ -6,7 +6,7 @@ import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart'; import 'package:hadi_hoda_flutter/common_ui/resources/my_colors.dart'; import 'package:hadi_hoda_flutter/common_ui/resources/my_spaces.dart'; import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart'; -import 'package:hadi_hoda_flutter/core/utils/check_platform.dart'; +import 'package:hadi_hoda_flutter/core/utils/set_platform_size.dart'; import 'package:hadi_hoda_flutter/core/widgets/about_us_dialog/styles/background.dart'; import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; import 'package:hadi_hoda_flutter/features/question/domain/entity/hadith_entity.dart'; @@ -37,7 +37,7 @@ class HadithDialog extends StatelessWidget { child: Center( child: Padding( padding: EdgeInsets.symmetric( - horizontal: checkSize( + horizontal: setSize( context: context, mobile: 18, tablet: 120, @@ -65,14 +65,14 @@ class HadithDialog extends StatelessWidget { ), ), Positioned( - right: checkSize(context: context, mobile: 30, tablet: 40), + right: setSize(context: context, mobile: 30, tablet: 40), top: -12, child: GestureDetector( onTap: context.pop, behavior: HitTestBehavior.opaque, child: MyImage( image: MyAssets.closeBtn, - size: checkSize(context: context, mobile: 40, tablet: 60), + size: setSize(context: context, mobile: 40, tablet: 60), ), ), ), diff --git a/lib/features/intro/presentation/bloc/intro_bloc.dart b/lib/features/intro/presentation/bloc/intro_bloc.dart index 595975f..127197b 100644 --- a/lib/features/intro/presentation/bloc/intro_bloc.dart +++ b/lib/features/intro/presentation/bloc/intro_bloc.dart @@ -1,23 +1,48 @@ import 'dart:async'; import 'package:bloc/bloc.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:go_router/go_router.dart'; +import 'package:hadi_hoda_flutter/core/routers/my_routes.dart'; +import 'package:hadi_hoda_flutter/core/utils/context_provider.dart'; import 'package:hadi_hoda_flutter/features/intro/presentation/bloc/intro_event.dart'; import 'package:hadi_hoda_flutter/features/intro/presentation/bloc/intro_state.dart'; +import 'package:hadi_hoda_flutter/features/intro/presentation/ui/screens/intro_1_screen.dart'; +import 'package:hadi_hoda_flutter/features/intro/presentation/ui/screens/intro_2_screen.dart'; +import 'package:hadi_hoda_flutter/features/intro/presentation/ui/screens/intro_3_screen.dart'; +import 'package:hadi_hoda_flutter/features/intro/presentation/ui/screens/intro_4_screen.dart'; +import 'package:hadi_hoda_flutter/features/intro/presentation/ui/screens/intro_5_screen.dart'; class IntroBloc extends Bloc { /// ------------constructor------------ IntroBloc() : super(const IntroState()){ - on(_getIntroEvent); + on(_changeIntroEvent); } /// ------------UseCases------------ /// ------------Variables------------ + final List intros = [ + Intro1Screen(key: Key('0')), + Intro2Screen(key: Key('1')), + Intro3Screen(key: Key('2')), + Intro4Screen(key: Key('3')), + Intro5Screen(key: Key('4')), + ]; /// ------------Controllers------------ /// ------------Functions------------ + void goToLevelPage(){ + ContextProvider.context.go(Routes.levelPage); + } /// ------------Api Calls------------ - FutureOr _getIntroEvent(event, emit) async {} + FutureOr _changeIntroEvent(ChangeIntroEvent event, Emitter emit) async { + if (state.currentIntro < intros.length - 1) { + emit(state.copyWith(currentIntro: state.currentIntro + 1)); + } else { + goToLevelPage(); + } + } } diff --git a/lib/features/intro/presentation/bloc/intro_event.dart b/lib/features/intro/presentation/bloc/intro_event.dart index 4bdd16b..5a38075 100644 --- a/lib/features/intro/presentation/bloc/intro_event.dart +++ b/lib/features/intro/presentation/bloc/intro_event.dart @@ -2,4 +2,4 @@ sealed class IntroEvent { const IntroEvent(); } -class GetIntroEvent extends IntroEvent {} +class ChangeIntroEvent extends IntroEvent {} diff --git a/lib/features/intro/presentation/bloc/intro_state.dart b/lib/features/intro/presentation/bloc/intro_state.dart index 2c7fd3f..0181124 100644 --- a/lib/features/intro/presentation/bloc/intro_state.dart +++ b/lib/features/intro/presentation/bloc/intro_state.dart @@ -2,14 +2,20 @@ import 'package:hadi_hoda_flutter/core/status/base_status.dart'; class IntroState { final BaseStatus getIntroStatus; + final int currentIntro; - const IntroState({this.getIntroStatus = const BaseInit()}); + const IntroState({ + this.getIntroStatus = const BaseInit(), + this.currentIntro = 0, + }); IntroState copyWith({ BaseStatus? getIntroStatus, + int? currentIntro, }) { return IntroState( getIntroStatus: getIntroStatus ?? this.getIntroStatus, + currentIntro: currentIntro ?? this.currentIntro, ); } } diff --git a/lib/features/intro/presentation/ui/intro_page.dart b/lib/features/intro/presentation/ui/intro_page.dart index 9de0ae2..2c20d18 100644 --- a/lib/features/intro/presentation/ui/intro_page.dart +++ b/lib/features/intro/presentation/ui/intro_page.dart @@ -1,10 +1,63 @@ import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:hadi_hoda_flutter/common_ui/resources/my_colors.dart'; +import 'package:hadi_hoda_flutter/common_ui/resources/my_spaces.dart'; +import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart'; +import 'package:hadi_hoda_flutter/core/utils/my_localization.dart'; +import 'package:hadi_hoda_flutter/features/intro/presentation/bloc/intro_bloc.dart'; +import 'package:hadi_hoda_flutter/features/intro/presentation/bloc/intro_event.dart'; +import 'package:hadi_hoda_flutter/features/intro/presentation/bloc/intro_state.dart'; class IntroPage extends StatelessWidget { const IntroPage({super.key}); @override Widget build(BuildContext context) { - return const Scaffold(); + return Scaffold( + body: SizedBox.expand( + child: GestureDetector( + onTap: () => context.read().add(ChangeIntroEvent()), + child: Stack( + children: [ + _mainScreen(), + _skipButton(context), + ], + ), + ), + ), + ); + } + + BlocBuilder _mainScreen() { + return BlocBuilder( + builder: (context, state) => AnimatedSwitcher( + duration: Duration(milliseconds: 200), + reverseDuration: Duration(milliseconds: 200), + switchInCurve: Curves.linear, + switchOutCurve: Curves.linear, + child: context.read().intros[state.currentIntro], + transitionBuilder: (child, animation) => + FadeTransition(opacity: animation, child: child), + ), + ); + } + + PositionedDirectional _skipButton(BuildContext context) { + return PositionedDirectional( + start: MySpaces.s30, + bottom: MySpaces.s16, + child: TextButton( + onPressed: () => context.read().goToLevelPage(), + style: TextButton.styleFrom( + foregroundColor: MyColors.white.withValues(alpha: 0.7), + ), + child: Text( + context.translate.skip, + style: MYTextStyle.button2.copyWith( + color: MyColors.white.withValues(alpha: 0.7), + ), + ), + ), + ); } } diff --git a/lib/features/intro/presentation/ui/screens/intro_1_screen.dart b/lib/features/intro/presentation/ui/screens/intro_1_screen.dart new file mode 100644 index 0000000..7e76806 --- /dev/null +++ b/lib/features/intro/presentation/ui/screens/intro_1_screen.dart @@ -0,0 +1,54 @@ +import 'package:flutter/material.dart'; +import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart'; +import 'package:hadi_hoda_flutter/common_ui/resources/my_spaces.dart'; +import 'package:hadi_hoda_flutter/core/utils/my_localization.dart'; +import 'package:hadi_hoda_flutter/core/utils/screen_size.dart'; +import 'package:hadi_hoda_flutter/core/utils/set_platform_size.dart'; +import 'package:hadi_hoda_flutter/core/widgets/animations/slide_up_fade.dart'; +import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; +import 'package:hadi_hoda_flutter/features/intro/presentation/ui/widgets/bubble_chat_widget.dart'; + +class Intro1Screen extends StatelessWidget { + const Intro1Screen({super.key}); + + @override + Widget build(BuildContext context) { + return Stack( + alignment: Alignment.center, + children: [ + Positioned.fill( + child: MyImage(image: MyAssets.intro_1, fit: BoxFit.cover), + ), + PositionedDirectional( + end: setSize( + context: context, + mobile: MySpaces.s10, + tablet: 0.15.w, + ), + top: setSize( + context: context, + mobile: 0.15.h, + tablet: 0.25.h, + ), + width: 290, + child: SlideUpFade( + delay: Duration(milliseconds: 300), + child: BubbleChatWidget( + text: context.translate.intro_1_1, + flip: true, + ), + ), + ), + PositionedDirectional( + start: setSize(context: context, mobile: MySpaces.s30, tablet: 0.2.w), + top: setSize(context: context, mobile: 0.3.h, tablet: 0.35.h), + width: 250, + child: SlideUpFade( + delay: Duration(milliseconds: 800), + child: BubbleChatWidget(text: context.translate.intro_1_2), + ), + ), + ], + ); + } +} diff --git a/lib/features/intro/presentation/ui/screens/intro_2_screen.dart b/lib/features/intro/presentation/ui/screens/intro_2_screen.dart new file mode 100644 index 0000000..47ed928 --- /dev/null +++ b/lib/features/intro/presentation/ui/screens/intro_2_screen.dart @@ -0,0 +1,37 @@ +import 'package:flutter/material.dart'; +import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart'; +import 'package:hadi_hoda_flutter/common_ui/resources/my_spaces.dart'; +import 'package:hadi_hoda_flutter/core/utils/my_localization.dart'; +import 'package:hadi_hoda_flutter/core/utils/screen_size.dart'; +import 'package:hadi_hoda_flutter/core/utils/set_platform_size.dart'; +import 'package:hadi_hoda_flutter/core/widgets/animations/slide_up_fade.dart'; +import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; +import 'package:hadi_hoda_flutter/features/intro/presentation/ui/widgets/bubble_chat_widget.dart'; + +class Intro2Screen extends StatelessWidget { + const Intro2Screen({super.key}); + + @override + Widget build(BuildContext context) { + return Stack( + alignment: Alignment.center, + children: [ + Positioned.fill( + child: Transform.flip( + flipX: true, + child: MyImage(image: MyAssets.intro_2, fit: BoxFit.cover), + ), + ), + PositionedDirectional( + end: setSize(context: context, mobile: MySpaces.s40, tablet: 0.3.w), + top: setSize(context: context, mobile: 0.17.h, tablet: 0.23.h), + width: 250, + child: SlideUpFade( + delay: Duration(milliseconds: 300), + child: BubbleChatWidget(text: context.translate.intro_2), + ), + ), + ], + ); + } +} diff --git a/lib/features/intro/presentation/ui/screens/intro_3_screen.dart b/lib/features/intro/presentation/ui/screens/intro_3_screen.dart new file mode 100644 index 0000000..3386651 --- /dev/null +++ b/lib/features/intro/presentation/ui/screens/intro_3_screen.dart @@ -0,0 +1,37 @@ +import 'package:flutter/material.dart'; +import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart'; +import 'package:hadi_hoda_flutter/common_ui/resources/my_spaces.dart'; +import 'package:hadi_hoda_flutter/core/utils/my_localization.dart'; +import 'package:hadi_hoda_flutter/core/utils/screen_size.dart'; +import 'package:hadi_hoda_flutter/core/utils/set_platform_size.dart'; +import 'package:hadi_hoda_flutter/core/widgets/animations/slide_up_fade.dart'; +import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; +import 'package:hadi_hoda_flutter/features/intro/presentation/ui/widgets/bubble_chat_widget.dart'; + +class Intro3Screen extends StatelessWidget { + const Intro3Screen({super.key}); + + @override + Widget build(BuildContext context) { + return Stack( + alignment: Alignment.center, + children: [ + Positioned.fill( + child: MyImage(image: MyAssets.intro_3, fit: BoxFit.cover), + ), + PositionedDirectional( + start: setSize(context: context, mobile: MySpaces.s30), + top: setSize(context: context, mobile: 180, tablet: 0.25.h), + width: 270, + child: SlideUpFade( + delay: Duration(milliseconds: 300), + child: BubbleChatWidget( + text: context.translate.intro_3, + flip: true, + ), + ), + ), + ], + ); + } +} diff --git a/lib/features/intro/presentation/ui/screens/intro_4_screen.dart b/lib/features/intro/presentation/ui/screens/intro_4_screen.dart new file mode 100644 index 0000000..e7a1562 --- /dev/null +++ b/lib/features/intro/presentation/ui/screens/intro_4_screen.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; +import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart'; +import 'package:hadi_hoda_flutter/common_ui/resources/my_spaces.dart'; +import 'package:hadi_hoda_flutter/core/utils/my_localization.dart'; +import 'package:hadi_hoda_flutter/core/utils/screen_size.dart'; +import 'package:hadi_hoda_flutter/core/utils/set_platform_size.dart'; +import 'package:hadi_hoda_flutter/core/widgets/animations/slide_up_fade.dart'; +import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; +import 'package:hadi_hoda_flutter/features/intro/presentation/ui/widgets/bubble_chat_widget.dart'; + +class Intro4Screen extends StatelessWidget { + const Intro4Screen({super.key}); + + @override + Widget build(BuildContext context) { + return Stack( + alignment: Alignment.center, + children: [ + Positioned.fill( + child: MyImage(image: MyAssets.intro_4, fit: BoxFit.cover), + ), + PositionedDirectional( + start: setSize(context: context, mobile: MySpaces.s10, tablet: 0.2.w), + bottom: setSize(context: context, mobile: 0.4.h, tablet: 0.4.h), + width: 237, + child: SlideUpFade( + delay: Duration(milliseconds: 300), + child: BubbleChatWidget( + text: context.translate.intro_4, + ), + ), + ), + ], + ); + } +} diff --git a/lib/features/intro/presentation/ui/screens/intro_5_screen.dart b/lib/features/intro/presentation/ui/screens/intro_5_screen.dart new file mode 100644 index 0000000..7228d8f --- /dev/null +++ b/lib/features/intro/presentation/ui/screens/intro_5_screen.dart @@ -0,0 +1,34 @@ +import 'package:flutter/material.dart'; +import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart'; +import 'package:hadi_hoda_flutter/core/utils/my_localization.dart'; +import 'package:hadi_hoda_flutter/core/utils/screen_size.dart'; +import 'package:hadi_hoda_flutter/core/utils/set_platform_size.dart'; +import 'package:hadi_hoda_flutter/core/widgets/animations/slide_up_fade.dart'; +import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; +import 'package:hadi_hoda_flutter/features/intro/presentation/ui/widgets/bubble_chat_widget.dart'; + +class Intro5Screen extends StatelessWidget { + const Intro5Screen({super.key}); + + @override + Widget build(BuildContext context) { + return Stack( + alignment: Alignment.center, + children: [ + Positioned.fill( + child: MyImage(image: MyAssets.intro_5, fit: BoxFit.cover), + ), + PositionedDirectional( + top: setSize(context: context, mobile: 0.37.h, tablet: 0.42.h), + width: 200, + child: SlideUpFade( + delay: Duration(milliseconds: 300), + child: BubbleChatWidget( + text: context.translate.intro_5, + ), + ), + ), + ], + ); + } +} diff --git a/lib/features/intro/presentation/ui/widgets/bubble_chat_widget.dart b/lib/features/intro/presentation/ui/widgets/bubble_chat_widget.dart new file mode 100644 index 0000000..729d6be --- /dev/null +++ b/lib/features/intro/presentation/ui/widgets/bubble_chat_widget.dart @@ -0,0 +1,91 @@ +import 'package:flutter/material.dart'; +import 'package:hadi_hoda_flutter/common_ui/resources/my_colors.dart'; +import 'package:hadi_hoda_flutter/common_ui/resources/my_spaces.dart'; +import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart'; + +class BubbleChatWidget extends StatelessWidget { + const BubbleChatWidget({ + super.key, + this.text, + this.width, + this.flip = false, + }); + + final String? text; + final double? width; + final bool flip; + + @override + Widget build(BuildContext context) { + return ClipPath( + clipper: _ShapeClipper(flip: flip), + child: Container( + width: width, + padding: EdgeInsets.only( + left: MySpaces.s18, + right: MySpaces.s18, + top: MySpaces.s16, + bottom: MySpaces.s28, + ), + decoration: BoxDecoration( + color: Color(0XFFF5E8D7).withValues(alpha: 0.5), + borderRadius: BorderRadius.all(Radius.circular(20)), + border: Border.all( + width: 1, + color: MyColors.white.withValues(alpha: 0.5), + ), + ), + child: Text( + text ?? '', + style: MYTextStyle.titr3.copyWith( + color: MyColors.black, + ), + ), + ), + ); + } +} + + + +class _ShapeClipper extends CustomClipper { + final bool flip; + + _ShapeClipper({this.flip = false}); // Add constructor + + @override + Path getClip(Size size) { + var path = Path(); + double w = size.width; + double h = size.height; + + // The drawing logic remains exactly the same + path.moveTo(w * 0.92, 0); + path.cubicTo(w * 0.96, 0, w, h * 0.05, w, h * 0.12); + path.lineTo(w, h * 0.70); + path.cubicTo(w, h * 0.78, w * 0.96, h * 0.83, w * 0.92, h * 0.83); + path.lineTo(w * 0.35, h * 0.83); + path.lineTo(w * 0.285, h); + path.lineTo(w * 0.20, h * 0.83); + path.lineTo(w * 0.08, h * 0.83); + path.cubicTo(w * 0.03, h * 0.83, 0, h * 0.78, 0, h * 0.70); + path.lineTo(0, h * 0.12); + path.cubicTo(0, h * 0.05, w * 0.03, 0, w * 0.08, 0); + path.close(); + + // If flip is true, transform the path horizontally + if (flip) { + final flipMatrix = Matrix4.identity() + ..translateByDouble(w, 0.0, 0.0, 1.0) + ..scaleByDouble(-1.0, 1.0, 1.0, 1.0); + return path.transform(flipMatrix.storage); + } + + return path; + } + + @override + bool shouldReclip(covariant _ShapeClipper oldClipper) { + return oldClipper.flip != flip; // Reclip if the flip state changes + } +} \ No newline at end of file diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index a4e49ea..c6c0b2b 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -17,5 +17,12 @@ "you_got_diamond": "You got the diamond", "view_map": "View Map", "go_next": "Go Next", - "you_win": "You Win!" + "you_win": "You Win!", + "skip": "Skip", + "intro_1_1": "Dinner is ready! Come quickly and wash your beautiful hands!", + "intro_1_2": "Mom! Our hands aren't that dirty! We'll just wipe them with a tissue!", + "intro_2": "The purity of faith... \nIt means cleanliness is a sign of faith!", + "intro_3": "These good deeds make our souls strong and beautiful!", + "intro_4": "Do you want to travel to the Promised Garden?", + "intro_5": "Yessss....\nWe are ready!" } \ No newline at end of file diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index ac161b7..fe54103 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -207,6 +207,48 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'You Win!'** String get you_win; + + /// No description provided for @skip. + /// + /// In en, this message translates to: + /// **'Skip'** + String get skip; + + /// No description provided for @intro_1_1. + /// + /// In en, this message translates to: + /// **'Dinner is ready! Come quickly and wash your beautiful hands!'** + String get intro_1_1; + + /// No description provided for @intro_1_2. + /// + /// In en, this message translates to: + /// **'Mom! Our hands aren\'t that dirty! We\'ll just wipe them with a tissue!'** + String get intro_1_2; + + /// No description provided for @intro_2. + /// + /// In en, this message translates to: + /// **'The purity of faith... \nIt means cleanliness is a sign of faith!'** + String get intro_2; + + /// No description provided for @intro_3. + /// + /// In en, this message translates to: + /// **'These good deeds make our souls strong and beautiful!'** + String get intro_3; + + /// No description provided for @intro_4. + /// + /// In en, this message translates to: + /// **'Do you want to travel to the Promised Garden?'** + String get intro_4; + + /// No description provided for @intro_5. + /// + /// In en, this message translates to: + /// **'Yessss....\nWe are ready!'** + String get intro_5; } class _AppLocalizationsDelegate diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 04b092b..ea0c2e8 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -66,4 +66,28 @@ class AppLocalizationsEn extends AppLocalizations { @override String get you_win => 'You Win!'; + + @override + String get skip => 'Skip'; + + @override + String get intro_1_1 => + 'Dinner is ready! Come quickly and wash your beautiful hands!'; + + @override + String get intro_1_2 => + 'Mom! Our hands aren\'t that dirty! We\'ll just wipe them with a tissue!'; + + @override + String get intro_2 => + 'The purity of faith... \nIt means cleanliness is a sign of faith!'; + + @override + String get intro_3 => 'These good deeds make our souls strong and beautiful!'; + + @override + String get intro_4 => 'Do you want to travel to the Promised Garden?'; + + @override + String get intro_5 => 'Yessss....\nWe are ready!'; } diff --git a/lib/main.dart b/lib/main.dart index 8eedb06..77f64d4 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -17,6 +17,7 @@ Future main() async { StoragePath.getDocumentDir(), initDataBase(), MyDevice.setPortrait(), + MyDevice.setImmersiveSticky(), ]); runApp(const MainApp()); } diff --git a/pubspec.yaml b/pubspec.yaml index 29ec071..c367fd7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -53,26 +53,23 @@ flutter: fonts: - - family: dinokids + - family: DinoKids fonts: - - asset: assets/fonts/dinokids.ttf - - family: marhey - fonts: - - asset: assets/fonts/Marhey-Light.ttf - weight: 100 - - asset: assets/fonts/Marhey-Light.ttf - weight: 200 - - asset: assets/fonts/Marhey-Light.ttf - weight: 300 - - asset: assets/fonts/Marhey-Regular.ttf + - asset: assets/fonts/DinoKids-Regular.ttf weight: 400 - - asset: assets/fonts/Marhey-Medium.ttf - weight: 500 + - family: Marhey + fonts: - asset: assets/fonts/Marhey-SemiBold.ttf weight: 600 - asset: assets/fonts/Marhey-Bold.ttf weight: 700 - - asset: assets/fonts/Marhey-Bold.ttf - weight: 800 - - asset: assets/fonts/Marhey-Bold.ttf - weight: 900 + - family: Baloo_2 + fonts: + - asset: assets/fonts/Baloo2-Medium.ttf + weight: 500 + - asset: assets/fonts/Baloo2-SemiBold.ttf + weight: 600 + - asset: assets/fonts/Baloo2-Bold.ttf + weight: 700 + - asset: assets/fonts/Baloo2-ExtraBold.ttf + weight: 800 \ No newline at end of file