diff --git a/assets/images/loading.png b/assets/images/loading.png new file mode 100644 index 0000000..cf91972 Binary files /dev/null and b/assets/images/loading.png differ diff --git a/assets/images/bubble_chat_left.svg b/assets/svg/bubble_chat_left.svg similarity index 100% rename from assets/images/bubble_chat_left.svg rename to assets/svg/bubble_chat_left.svg diff --git a/assets/images/bubble_chat_right.svg b/assets/svg/bubble_chat_right.svg similarity index 100% rename from assets/images/bubble_chat_right.svg rename to assets/svg/bubble_chat_right.svg diff --git a/assets/images/button.svg b/assets/svg/button.svg similarity index 100% rename from assets/images/button.svg rename to assets/svg/button.svg diff --git a/assets/images/button_2.svg b/assets/svg/button_2.svg similarity index 100% rename from assets/images/button_2.svg rename to assets/svg/button_2.svg diff --git a/assets/images/button_3.svg b/assets/svg/button_3.svg similarity index 100% rename from assets/images/button_3.svg rename to assets/svg/button_3.svg diff --git a/assets/images/close_btn.svg b/assets/svg/close_btn.svg similarity index 100% rename from assets/images/close_btn.svg rename to assets/svg/close_btn.svg diff --git a/assets/images/correct.svg b/assets/svg/correct.svg similarity index 100% rename from assets/images/correct.svg rename to assets/svg/correct.svg diff --git a/assets/images/done.svg b/assets/svg/done.svg similarity index 100% rename from assets/images/done.svg rename to assets/svg/done.svg diff --git a/assets/images/done_rounded.svg b/assets/svg/done_rounded.svg similarity index 100% rename from assets/images/done_rounded.svg rename to assets/svg/done_rounded.svg diff --git a/assets/images/facebook.svg b/assets/svg/facebook.svg similarity index 100% rename from assets/images/facebook.svg rename to assets/svg/facebook.svg diff --git a/assets/images/hand_point.svg b/assets/svg/hand_point.svg similarity index 100% rename from assets/images/hand_point.svg rename to assets/svg/hand_point.svg diff --git a/assets/images/home.svg b/assets/svg/home.svg similarity index 100% rename from assets/images/home.svg rename to assets/svg/home.svg diff --git a/assets/images/instagram.svg b/assets/svg/instagram.svg similarity index 100% rename from assets/images/instagram.svg rename to assets/svg/instagram.svg diff --git a/assets/images/lang.svg b/assets/svg/lang.svg similarity index 100% rename from assets/images/lang.svg rename to assets/svg/lang.svg diff --git a/assets/images/language.svg b/assets/svg/language.svg similarity index 100% rename from assets/images/language.svg rename to assets/svg/language.svg diff --git a/assets/images/location.svg b/assets/svg/location.svg similarity index 100% rename from assets/images/location.svg rename to assets/svg/location.svg diff --git a/assets/images/music.svg b/assets/svg/music.svg similarity index 100% rename from assets/images/music.svg rename to assets/svg/music.svg diff --git a/assets/images/music_off.svg b/assets/svg/music_off.svg similarity index 100% rename from assets/images/music_off.svg rename to assets/svg/music_off.svg diff --git a/assets/images/music_on.svg b/assets/svg/music_on.svg similarity index 100% rename from assets/images/music_on.svg rename to assets/svg/music_on.svg diff --git a/assets/images/new_horizon.svg b/assets/svg/new_horizon.svg similarity index 100% rename from assets/images/new_horizon.svg rename to assets/svg/new_horizon.svg diff --git a/assets/images/play.svg b/assets/svg/play.svg similarity index 100% rename from assets/images/play.svg rename to assets/svg/play.svg diff --git a/assets/images/theme.svg b/assets/svg/theme.svg similarity index 100% rename from assets/images/theme.svg rename to assets/svg/theme.svg diff --git a/assets/images/unmusic.svg b/assets/svg/unmusic.svg similarity index 100% rename from assets/images/unmusic.svg rename to assets/svg/unmusic.svg diff --git a/assets/images/whatsapp.svg b/assets/svg/whatsapp.svg similarity index 100% rename from assets/images/whatsapp.svg rename to assets/svg/whatsapp.svg diff --git a/assets/images/wrong.svg b/assets/svg/wrong.svg similarity index 100% rename from assets/images/wrong.svg rename to assets/svg/wrong.svg diff --git a/assets/images/youtube.svg b/assets/svg/youtube.svg similarity index 100% rename from assets/images/youtube.svg rename to assets/svg/youtube.svg diff --git a/lib/common_ui/resources/my_assets.dart b/lib/common_ui/resources/my_assets.dart index 23d84bb..7fbb1e5 100644 --- a/lib/common_ui/resources/my_assets.dart +++ b/lib/common_ui/resources/my_assets.dart @@ -3,47 +3,73 @@ class MyAssets { const MyAssets._internal(); factory MyAssets() => _i; + /// PNG, JPG static const String backgroundHome = 'assets/images/background_intro.png'; - static const String closeBtn = 'assets/images/close_btn.svg'; static const String hadiHoda = 'assets/images/hadi_hoda.png'; - static const String musicOff = 'assets/images/music_off.svg'; - static const String musicOn = 'assets/images/music_on.svg'; - static const String button = 'assets/images/button.svg'; - static const String button2 = 'assets/images/button_2.svg'; - static const String button3 = 'assets/images/button_3.svg'; - static const String theme = 'assets/images/theme.svg'; - static const String facebook = 'assets/images/facebook.svg'; - static const String whatsapp = 'assets/images/whatsapp.svg'; - static const String youtube = 'assets/images/youtube.svg'; - static const String instagram = 'assets/images/instagram.svg'; - static const String language = 'assets/images/language.svg'; - static const String newHorizon = 'assets/images/new_horizon.svg'; static const String khadijeLogo = 'assets/images/khadije_logo.png'; - static const String home = 'assets/images/home.svg'; - static const String music = 'assets/images/music.svg'; static const String pattern = 'assets/images/pattern.png'; static const String persons = 'assets/images/persons.png'; - static const String bubbleChatLeft = 'assets/images/bubble_chat_left.svg'; - static const String bubbleChatRight = 'assets/images/bubble_chat_right.svg'; static const String diamond = 'assets/images/diamond.png'; - static const String done = 'assets/images/done.svg'; - static const String correct = 'assets/images/correct.svg'; - static const String wrong = 'assets/images/wrong.svg'; - static const String handPoint = 'assets/images/hand_point.svg'; static const String mapBackground = 'assets/images/map_background.png'; static const String level = 'assets/images/level.png'; static const String finishedLevel = 'assets/images/finished_level.png'; static const String currentLevel = 'assets/images/current_level.png'; - static const String location = 'assets/images/location.svg'; - static const String play = 'assets/images/play.svg'; static const String homeButton = 'assets/images/home_button.png'; - static const String doneRounded = 'assets/images/done_rounded.svg'; - static const String lang = 'assets/images/lang.svg'; static const String error = 'assets/images/error.png'; static const String leaf = 'assets/images/leaf.png'; static const String happyPersons = 'assets/images/happy_persons.png'; static const String diamondBig = 'assets/images/diamond_big.png'; static const String ship = 'assets/images/ship.png'; static const String shiny = 'assets/images/shiny.png'; - static const String unMusic = 'assets/images/unmusic.svg'; + static const String loading = 'assets/images/loading.png'; + + /// SVG + static const String closeBtn = 'assets/svg/close_btn.svg'; + static const String musicOff = 'assets/svg/music_off.svg'; + static const String musicOn = 'assets/svg/music_on.svg'; + static const String button = 'assets/svg/button.svg'; + static const String button2 = 'assets/svg/button_2.svg'; + static const String button3 = 'assets/svg/button_3.svg'; + static const String theme = 'assets/svg/theme.svg'; + static const String facebook = 'assets/svg/facebook.svg'; + static const String whatsapp = 'assets/svg/whatsapp.svg'; + static const String youtube = 'assets/svg/youtube.svg'; + static const String instagram = 'assets/svg/instagram.svg'; + static const String language = 'assets/svg/language.svg'; + static const String newHorizon = 'assets/svg/new_horizon.svg'; + static const String home = 'assets/svg/home.svg'; + static const String music = 'assets/svg/music.svg'; + static const String bubbleChatLeft = 'assets/svg/bubble_chat_left.svg'; + static const String bubbleChatRight = 'assets/svg/bubble_chat_right.svg'; + static const String done = 'assets/svg/done.svg'; + static const String correct = 'assets/svg/correct.svg'; + static const String wrong = 'assets/svg/wrong.svg'; + static const String handPoint = 'assets/svg/hand_point.svg'; + static const String location = 'assets/svg/location.svg'; + static const String play = 'assets/svg/play.svg'; + static const String doneRounded = 'assets/svg/done_rounded.svg'; + static const String lang = 'assets/svg/lang.svg'; + static const String unMusic = 'assets/svg/unmusic.svg'; + + + static final List images = [ + backgroundHome, + hadiHoda, + khadijeLogo, + pattern, + persons, + diamond, + mapBackground, + level, + finishedLevel, + currentLevel, + homeButton, + error, + leaf, + happyPersons, + diamondBig, + ship, + shiny, + loading, + ]; } \ 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 1223ae8..c0f9552 100644 --- a/lib/common_ui/theme/my_theme.dart +++ b/lib/common_ui/theme/my_theme.dart @@ -8,9 +8,9 @@ class MyTheme { const MyTheme._internal(); factory MyTheme() => _i; - static final ThemeData light = ThemeData(brightness: Brightness.light); + static final ThemeData light = ThemeData(brightness: Brightness.dark); - static final ThemeData dark = ThemeData(brightness: Brightness.dark); + static final ThemeData dark = ThemeData(brightness: Brightness.light); static Map get lightColors => { ColorsName.primaryColor: MyColors.white, diff --git a/lib/core/constants/my_constants.dart b/lib/core/constants/my_constants.dart index 15c0889..c157bdd 100644 --- a/lib/core/constants/my_constants.dart +++ b/lib/core/constants/my_constants.dart @@ -11,6 +11,6 @@ class MyConstants { static const String downloadedAudio = 'DOWNLOADED_AUDIO'; static const String extractedAudio = 'EXTRACTED_AUDIO'; static const String selectLanguage = 'SELECT_LANGUAGE'; - static const String firstLanguagePage = 'FIRST_LANGUAGE_PAGE'; + static const String firstDownload = 'FIRST_DOWNLOAD'; static const String currentLevel = 'CURRENT_LEVEL'; } \ No newline at end of file diff --git a/lib/core/middlewares/my_middlewares.dart b/lib/core/middlewares/my_middlewares.dart new file mode 100644 index 0000000..cad56f8 --- /dev/null +++ b/lib/core/middlewares/my_middlewares.dart @@ -0,0 +1,23 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:hadi_hoda_flutter/core/constants/my_constants.dart'; +import 'package:hadi_hoda_flutter/core/routers/my_routes.dart'; +import 'package:hadi_hoda_flutter/core/utils/local_storage.dart'; + +class MyMiddlewares { + static const MyMiddlewares _i = MyMiddlewares._internal(); + const MyMiddlewares._internal(); + factory MyMiddlewares() => _i; + + static FutureOr intro(BuildContext context, GoRouterState state) { + final String? firstDownload = LocalStorage.readData( + key: MyConstants.firstDownload); + if (firstDownload != 'true') { + return Routes.languagePage; + } else { + return null; + } + } +} diff --git a/lib/core/routers/my_routes.dart b/lib/core/routers/my_routes.dart index 0f9ef04..406fe07 100644 --- a/lib/core/routers/my_routes.dart +++ b/lib/core/routers/my_routes.dart @@ -1,7 +1,9 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; +import 'package:hadi_hoda_flutter/core/middlewares/my_middlewares.dart'; import 'package:hadi_hoda_flutter/core/utils/context_provider.dart'; import 'package:hadi_hoda_flutter/features/download/presentation/bloc/download_bloc.dart'; +import 'package:hadi_hoda_flutter/features/download/presentation/bloc/download_event.dart'; import 'package:hadi_hoda_flutter/features/download/presentation/ui/download_page.dart'; import 'package:hadi_hoda_flutter/features/home/presentation/bloc/home_bloc.dart'; import 'package:hadi_hoda_flutter/features/home/presentation/ui/home_page.dart'; @@ -38,8 +40,9 @@ GoRouter get appPages => GoRouter( GoRoute( name: Routes.introPage, path: Routes.introPage, + redirect: MyMiddlewares.intro, builder: (context, state) => BlocProvider( - create: (context) => IntroBloc(locator(), locator()), + create: (context) => IntroBloc(), child: const IntroPage(), ), ), @@ -47,7 +50,12 @@ GoRouter get appPages => GoRouter( name: Routes.downloadPage, path: Routes.downloadPage, builder: (context, state) => BlocProvider( - create: (context) => DownloadBloc(locator(), locator(), locator()), + create: (context) => DownloadBloc( + locator(), + locator(), + locator(), + locator(), + )..add(GetImagesEvent()), child: const DownloadPage(), ), ), 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 ec274f3..5b44a9b 100644 --- a/lib/core/widgets/about_us_dialog/about_us_dialog.dart +++ b/lib/core/widgets/about_us_dialog/about_us_dialog.dart @@ -6,9 +6,9 @@ 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_image.dart'; import 'package:hadi_hoda_flutter/core/utils/my_localization.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'; Future showAboutUsDialog({required BuildContext context}) async { await showDialog( diff --git a/lib/core/widgets/animations/rotation_anim.dart b/lib/core/widgets/animations/rotation_anim.dart new file mode 100644 index 0000000..ea4d9e9 --- /dev/null +++ b/lib/core/widgets/animations/rotation_anim.dart @@ -0,0 +1,50 @@ +import 'package:flutter/material.dart'; + +class RotationAnim extends StatefulWidget { + const RotationAnim({super.key, required this.child}); + + final Widget child; + + @override + State createState() => _RotationAnimState(); +} + +class _RotationAnimState extends State + with SingleTickerProviderStateMixin { + late AnimationController _controller; + late Animation _animation; + + @override + void initState() { + super.initState(); + _controller = AnimationController( + vsync: this, + duration: Duration(seconds: 20), + ); + _animation = Tween( + begin: 0, + end: 20, + ).animate(CurvedAnimation(parent: _controller, curve: Curves.linear)); + + _controller.repeat(); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return AnimatedBuilder( + animation: _controller, + child: widget.child, + builder: (context, child) => RotationTransition( + turns: _animation, + alignment: Alignment.center, + child: child, + ), + ); + } +} diff --git a/lib/core/widgets/answer_box/styles/picture_box.dart b/lib/core/widgets/answer_box/styles/picture_box.dart index 64550c0..b1b1976 100644 --- a/lib/core/widgets/answer_box/styles/picture_box.dart +++ b/lib/core/widgets/answer_box/styles/picture_box.dart @@ -7,7 +7,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/my_image.dart'; +import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; import 'package:hadi_hoda_flutter/features/question/presentation/ui/widgets/black_white_effect.dart'; class AnswerPictureBox extends StatefulWidget { diff --git a/lib/core/widgets/button/my_button.dart b/lib/core/widgets/button/my_button.dart index a0b48fd..a399435 100644 --- a/lib/core/widgets/button/my_button.dart +++ b/lib/core/widgets/button/my_button.dart @@ -3,8 +3,8 @@ 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/my_image.dart'; import 'package:hadi_hoda_flutter/core/widgets/button/enum/button_type.dart'; +import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; class MyButton extends StatelessWidget { const MyButton({ diff --git a/lib/core/widgets/confetti/my_confetti.dart b/lib/core/widgets/confetti/my_confetti.dart index 1a101f9..a5f0486 100644 --- a/lib/core/widgets/confetti/my_confetti.dart +++ b/lib/core/widgets/confetti/my_confetti.dart @@ -15,9 +15,7 @@ class MyConfetti extends StatelessWidget { shouldLoop: false, blastDirectionality: BlastDirectionality.explosive, blastDirection: pi / 2, - // ↓ down - gravity: 0.2, - // let pieces fall + gravity: 1, emissionFrequency: 0.5, numberOfParticles: 15, particleDrag: 0.1, diff --git a/lib/core/widgets/error/error_state.dart b/lib/core/widgets/error/error_state.dart index d39e965..e23542d 100644 --- a/lib/core/widgets/error/error_state.dart +++ b/lib/core/widgets/error/error_state.dart @@ -4,8 +4,8 @@ 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/gap.dart'; -import 'package:hadi_hoda_flutter/core/utils/my_image.dart'; import 'package:hadi_hoda_flutter/core/utils/my_localization.dart'; +import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; class ErrorState extends StatelessWidget { const ErrorState({super.key, this.onTap}); diff --git a/lib/core/widgets/hadith_dialog/hadith_dialog.dart b/lib/core/widgets/hadith_dialog/hadith_dialog.dart index ff5d098..eaa2227 100644 --- a/lib/core/widgets/hadith_dialog/hadith_dialog.dart +++ b/lib/core/widgets/hadith_dialog/hadith_dialog.dart @@ -7,8 +7,8 @@ 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/my_image.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'; Future showHadithDialog({required BuildContext context}) async { await showDialog( diff --git a/lib/core/utils/my_image.dart b/lib/core/widgets/images/my_image.dart similarity index 85% rename from lib/core/utils/my_image.dart rename to lib/core/widgets/images/my_image.dart index bf977e3..b3b8cd8 100644 --- a/lib/core/utils/my_image.dart +++ b/lib/core/widgets/images/my_image.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; +import 'package:vector_graphics/vector_graphics.dart'; class MyImage extends StatelessWidget { const MyImage({ @@ -25,8 +25,8 @@ class MyImage extends StatelessWidget { height: size, ); } else { - return SvgPicture.asset( - image, + return VectorGraphic( + loader: AssetBytesLoader(image), fit: fit ?? BoxFit.contain, width: size, height: size, diff --git a/lib/core/widgets/showcase/question_showcase.dart b/lib/core/widgets/showcase/question_showcase.dart index 79c4f5b..03be7c0 100644 --- a/lib/core/widgets/showcase/question_showcase.dart +++ b/lib/core/widgets/showcase/question_showcase.dart @@ -2,8 +2,8 @@ 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_colors.dart'; import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart'; -import 'package:hadi_hoda_flutter/core/utils/my_image.dart'; import 'package:hadi_hoda_flutter/core/utils/screen_size.dart'; +import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; import 'package:showcaseview/showcaseview.dart'; class QuestionShowcase extends StatelessWidget { diff --git a/lib/features/download/data/datasource/download_datasource.dart b/lib/features/download/data/datasource/download_datasource.dart index def3308..5c3ba31 100644 --- a/lib/features/download/data/datasource/download_datasource.dart +++ b/lib/features/download/data/datasource/download_datasource.dart @@ -16,6 +16,7 @@ import 'package:hadi_hoda_flutter/features/level/domain/entity/total_data_entity import 'package:hive/hive.dart'; abstract class IDownloadDatasource { + Future getImages(); Future getAudios(); Future saveLevels(); Stream loadingStream(); @@ -27,6 +28,54 @@ class DownloadDatasourceImpl implements IDownloadDatasource { DownloadDatasourceImpl(this.httpRequest); + @override + Future getImages() async { + final String filePath = '${StoragePath.documentDir.path}/images.zip'; + + if (LocalStorage.readData(key: MyConstants.downloadedImage) != 'true') { + await httpRequest.download( + urlPath: MyApi.images, + savePath: filePath, + onReceive: (count, total) { + streamController.add(DownloadEntity( + count: count / 1, + total: total / 1, + percent: (count / total) * 100, + )); + }, + ).then((value) async { + await LocalStorage.saveData( + key: MyConstants.downloadedImage, + value: 'true', + ); + }); + } + + try{ + if (LocalStorage.readData(key: MyConstants.extractedImage) != 'true') { + final File file = File(filePath); + final Directory directory = Directory('${StoragePath.documentDir.path}/'); + await ZipFile.extractToDirectory( + zipFile: file, + destinationDir: directory, + onExtracting: (zipEntry, progress) { + return ZipFileOperation.includeItem; + }, + ).then((value) async { + await Future.wait([ + LocalStorage.saveData( + key: MyConstants.extractedImage, + value: 'true', + ), + file.delete(recursive: true), + ]); + }); + } + } catch (e){ + throw MyException(errorMessage: '$e'); + } + } + @override Future getAudios() async { final String filePath = '${StoragePath.documentDir.path}/audios.zip'; @@ -52,7 +101,7 @@ class DownloadDatasourceImpl implements IDownloadDatasource { key: MyConstants.downloadedAudio, value: 'true', ); - },); + }); } try{ @@ -76,10 +125,6 @@ class DownloadDatasourceImpl implements IDownloadDatasource { file.delete(recursive: true), ]); }); - } else { - streamController.add(DownloadEntity(percent: 50)); - await Future.delayed(Duration(milliseconds: 150)); - streamController.add(DownloadEntity(percent: 100)); } } catch (e){ throw MyException(errorMessage: '$e'); @@ -105,9 +150,7 @@ class DownloadDatasourceImpl implements IDownloadDatasource { response?['result'], (json) => LevelModel.fromJson(json), ); - await Future.wait([ - data.add(TotalDataEntity(code: selectedLanguage, levels: levels)), - ]); + await data.add(TotalDataEntity(code: selectedLanguage, levels: levels)); } } diff --git a/lib/features/download/data/repository_impl/download_repository_impl.dart b/lib/features/download/data/repository_impl/download_repository_impl.dart index 9fd8b54..13917f6 100644 --- a/lib/features/download/data/repository_impl/download_repository_impl.dart +++ b/lib/features/download/data/repository_impl/download_repository_impl.dart @@ -11,6 +11,22 @@ class DownloadRepositoryImpl implements IDownloadRepository { const DownloadRepositoryImpl(this.datasource); + @override + Future> getImages() async { + try { + await datasource.getImages(); + return DataState.success(NoParams()); + } on MyException catch (e) { + return DataState.error(e); + } catch (e) { + if (kDebugMode) { + rethrow; + } else { + return DataState.error(MyException(errorMessage: '$e')); + } + } + } + @override Future> getAudios() async { try { diff --git a/lib/features/download/domain/repository/download_repository.dart b/lib/features/download/domain/repository/download_repository.dart index b7ffbd5..ab53e49 100644 --- a/lib/features/download/domain/repository/download_repository.dart +++ b/lib/features/download/domain/repository/download_repository.dart @@ -4,6 +4,7 @@ import 'package:hadi_hoda_flutter/core/utils/data_state.dart'; import 'package:hadi_hoda_flutter/features/download/domain/entities/download_entity.dart'; abstract class IDownloadRepository { + Future> getImages(); Future> getAudios(); Future> saveLevels(); Stream loadingStream(); diff --git a/lib/features/intro/domain/usecases/get_images_usecase.dart b/lib/features/download/domain/usecases/get_images_usecase.dart similarity index 78% rename from lib/features/intro/domain/usecases/get_images_usecase.dart rename to lib/features/download/domain/usecases/get_images_usecase.dart index 3774894..f91e1d6 100644 --- a/lib/features/intro/domain/usecases/get_images_usecase.dart +++ b/lib/features/download/domain/usecases/get_images_usecase.dart @@ -2,10 +2,10 @@ import 'package:hadi_hoda_flutter/core/error_handler/my_exception.dart'; import 'package:hadi_hoda_flutter/core/params/no_params.dart'; import 'package:hadi_hoda_flutter/core/usecase/usecase.dart'; import 'package:hadi_hoda_flutter/core/utils/data_state.dart'; -import 'package:hadi_hoda_flutter/features/intro/domain/repository/intro_repository.dart'; +import 'package:hadi_hoda_flutter/features/download/domain/repository/download_repository.dart'; class GetImagesUseCase implements UseCase { - final IIntroRepository repository; + final IDownloadRepository repository; const GetImagesUseCase(this.repository); diff --git a/lib/features/download/domain/usecases/loading_stream_audio_usecase.dart b/lib/features/download/domain/usecases/loading_stream_usecase.dart similarity index 78% rename from lib/features/download/domain/usecases/loading_stream_audio_usecase.dart rename to lib/features/download/domain/usecases/loading_stream_usecase.dart index 4af13e0..cb0fa54 100644 --- a/lib/features/download/domain/usecases/loading_stream_audio_usecase.dart +++ b/lib/features/download/domain/usecases/loading_stream_usecase.dart @@ -1,10 +1,10 @@ import 'package:hadi_hoda_flutter/features/download/domain/entities/download_entity.dart'; import 'package:hadi_hoda_flutter/features/download/domain/repository/download_repository.dart'; -class LoadingStreamAudioUseCase { +class LoadingStreamUseCase { final IDownloadRepository repository; - const LoadingStreamAudioUseCase(this.repository); + const LoadingStreamUseCase(this.repository); Stream call() { return repository.loadingStream(); diff --git a/lib/features/download/presentation/bloc/download_bloc.dart b/lib/features/download/presentation/bloc/download_bloc.dart index 8672d8e..09ed742 100644 --- a/lib/features/download/presentation/bloc/download_bloc.dart +++ b/lib/features/download/presentation/bloc/download_bloc.dart @@ -2,13 +2,16 @@ import 'dart:async'; import 'package:bloc/bloc.dart'; import 'package:go_router/go_router.dart'; +import 'package:hadi_hoda_flutter/core/constants/my_constants.dart'; import 'package:hadi_hoda_flutter/core/params/no_params.dart'; import 'package:hadi_hoda_flutter/core/routers/my_routes.dart'; import 'package:hadi_hoda_flutter/core/status/base_status.dart'; import 'package:hadi_hoda_flutter/core/utils/context_provider.dart'; +import 'package:hadi_hoda_flutter/core/utils/local_storage.dart'; import 'package:hadi_hoda_flutter/features/download/domain/entities/download_entity.dart'; import 'package:hadi_hoda_flutter/features/download/domain/usecases/get_audios_usecase.dart'; -import 'package:hadi_hoda_flutter/features/download/domain/usecases/loading_stream_audio_usecase.dart'; +import 'package:hadi_hoda_flutter/features/download/domain/usecases/get_images_usecase.dart'; +import 'package:hadi_hoda_flutter/features/download/domain/usecases/loading_stream_usecase.dart'; import 'package:hadi_hoda_flutter/features/download/domain/usecases/save_levels_usecase.dart'; import 'package:hadi_hoda_flutter/features/download/presentation/bloc/download_event.dart'; import 'package:hadi_hoda_flutter/features/download/presentation/bloc/download_state.dart'; @@ -16,20 +19,23 @@ import 'package:hadi_hoda_flutter/features/download/presentation/bloc/download_s class DownloadBloc extends Bloc { /// ------------constructor------------ DownloadBloc( + this._getImagesUseCase, this._getAudiosUseCase, this._loadingStreamUseCase, this._saveLevelsUseCase, ) : super(const DownloadState()) { + on(_getImagesEvent); on(_getAudiosEvent); on(_saveLevelsEvent); loadingStream = _loadingStreamUseCase(); } /// ------------UseCases------------ + final GetImagesUseCase _getImagesUseCase; final GetAudiosUseCase _getAudiosUseCase; final SaveLevelsUseCase _saveLevelsUseCase; - final LoadingStreamAudioUseCase _loadingStreamUseCase; + final LoadingStreamUseCase _loadingStreamUseCase; /// ------------Variables------------ Stream loadingStream = Stream.empty(); @@ -39,6 +45,22 @@ class DownloadBloc extends Bloc { /// ------------Functions------------ /// ------------Api Calls------------ + FutureOr _getImagesEvent( + GetImagesEvent event, + Emitter emit, + ) async { + await _getImagesUseCase(NoParams()).then((value) { + value.fold( + (data) { + add(GetAudiosEvent()); + }, + (error) async { + emit(state.copyWith(getFilesStatus: BaseError(error.errorMessage))); + }, + ); + }); + } + FutureOr _getAudiosEvent( GetAudiosEvent event, Emitter emit, @@ -63,7 +85,10 @@ class DownloadBloc extends Bloc { await _saveLevelsUseCase(NoParams()).then((value) => value.fold( (data) async { - ContextProvider.context.goNamed(Routes.homePage); + await LocalStorage.saveData(key: MyConstants.firstDownload, value: 'true'); + if(ContextProvider.context.mounted){ + ContextProvider.context.goNamed(Routes.homePage); + } }, (error) { emit(state.copyWith(getFilesStatus: BaseError(error.errorMessage))); diff --git a/lib/features/download/presentation/bloc/download_event.dart b/lib/features/download/presentation/bloc/download_event.dart index 9d05b54..ec62661 100644 --- a/lib/features/download/presentation/bloc/download_event.dart +++ b/lib/features/download/presentation/bloc/download_event.dart @@ -1,5 +1,6 @@ sealed class DownloadEvent { const DownloadEvent(); } +class GetImagesEvent extends DownloadEvent {} class GetAudiosEvent extends DownloadEvent {} class SaveLevelsEvent extends DownloadEvent {} diff --git a/lib/features/download/presentation/ui/download_page.dart b/lib/features/download/presentation/ui/download_page.dart index c7533b3..4d6d1ba 100644 --- a/lib/features/download/presentation/ui/download_page.dart +++ b/lib/features/download/presentation/ui/download_page.dart @@ -6,30 +6,19 @@ 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/status/base_status.dart'; import 'package:hadi_hoda_flutter/core/utils/convert_size.dart'; -import 'package:hadi_hoda_flutter/core/utils/my_image.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/widgets/error/error_state.dart'; +import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; import 'package:hadi_hoda_flutter/features/download/domain/entities/download_entity.dart'; import 'package:hadi_hoda_flutter/features/download/presentation/bloc/download_bloc.dart'; import 'package:hadi_hoda_flutter/features/download/presentation/bloc/download_event.dart'; import 'package:hadi_hoda_flutter/features/download/presentation/bloc/download_state.dart'; import 'package:hadi_hoda_flutter/features/download/presentation/ui/widgets/download_loading_widget.dart'; -class DownloadPage extends StatefulWidget { +class DownloadPage extends StatelessWidget { const DownloadPage({super.key}); - @override - State createState() => _DownloadPageState(); -} - -class _DownloadPageState extends State { - @override - void initState() { - super.initState(); - context.read().add(GetAudiosEvent()); - } - @override Widget build(BuildContext context) { return Scaffold( @@ -66,7 +55,7 @@ class _DownloadPageState extends State { horizontal: 60, ), child: ErrorState( - onTap: () => context.read().add(GetAudiosEvent()), + onTap: () => context.read().add(GetImagesEvent()), ), ); } else { diff --git a/lib/features/home/presentation/bloc/home_bloc.dart b/lib/features/home/presentation/bloc/home_bloc.dart index 1ba9839..219c7ed 100644 --- a/lib/features/home/presentation/bloc/home_bloc.dart +++ b/lib/features/home/presentation/bloc/home_bloc.dart @@ -3,11 +3,15 @@ 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/constants/my_constants.dart'; import 'package:hadi_hoda_flutter/core/routers/my_routes.dart'; import 'package:hadi_hoda_flutter/core/services/audio_service.dart'; +import 'package:hadi_hoda_flutter/core/utils/local_storage.dart'; import 'package:hadi_hoda_flutter/core/widgets/about_us_dialog/about_us_dialog.dart'; import 'package:hadi_hoda_flutter/features/home/presentation/bloc/home_event.dart'; import 'package:hadi_hoda_flutter/features/home/presentation/bloc/home_state.dart'; +import 'package:hadi_hoda_flutter/features/level/domain/entity/total_data_entity.dart'; +import 'package:hive/hive.dart'; class HomeBloc extends Bloc { /// ------------constructor------------ @@ -28,7 +32,17 @@ class HomeBloc extends Bloc { /// ------------Functions------------ void goToLevelPage(BuildContext context){ - context.pushNamed(Routes.levelPage); + final String? selectedLanguage = LocalStorage.readData(key: MyConstants.selectLanguage); + final Box dataBox = Hive.box(MyConstants.levelBox); + final TotalDataEntity findData = dataBox.values.singleWhere( + (e) => e.code == selectedLanguage, + orElse: () => TotalDataEntity(), + ); + if (findData.levels?.isNotEmpty ?? false) { + context.pushNamed(Routes.levelPage); + } else { + context.goNamed(Routes.downloadPage); + } } void goToLanguagePage(BuildContext context){ diff --git a/lib/features/home/presentation/ui/home_page.dart b/lib/features/home/presentation/ui/home_page.dart index 2905c4f..9b6490d 100644 --- a/lib/features/home/presentation/ui/home_page.dart +++ b/lib/features/home/presentation/ui/home_page.dart @@ -2,11 +2,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.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_image.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/widgets/button/enum/button_type.dart'; import 'package:hadi_hoda_flutter/core/widgets/button/my_button.dart'; +import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; import 'package:hadi_hoda_flutter/features/home/presentation/bloc/home_bloc.dart'; class HomePage extends StatelessWidget { diff --git a/lib/features/intro/data/datasource/intro_datasource.dart b/lib/features/intro/data/datasource/intro_datasource.dart deleted file mode 100644 index 7a48b46..0000000 --- a/lib/features/intro/data/datasource/intro_datasource.dart +++ /dev/null @@ -1,78 +0,0 @@ -import 'dart:async'; -import 'dart:io'; - -import 'package:flutter_archive/flutter_archive.dart'; -import 'package:hadi_hoda_flutter/core/constants/my_api.dart'; -import 'package:hadi_hoda_flutter/core/constants/my_constants.dart'; -import 'package:hadi_hoda_flutter/core/error_handler/my_exception.dart'; -import 'package:hadi_hoda_flutter/core/network/http_request.dart'; -import 'package:hadi_hoda_flutter/core/utils/local_storage.dart'; -import 'package:hadi_hoda_flutter/core/utils/storage_path.dart'; -import 'package:hadi_hoda_flutter/features/download/domain/entities/download_entity.dart'; - -abstract class IIntroDatasource { - Future getImages(); - Stream loadingStream(); -} - -class IntroDatasourceImpl implements IIntroDatasource { - final IHttpRequest httpRequest; - final StreamController streamController = StreamController.broadcast(); - - IntroDatasourceImpl(this.httpRequest); - - @override - Future getImages() async { - final String filePath = '${StoragePath.documentDir.path}/images.zip'; - - if (LocalStorage.readData(key: MyConstants.downloadedImage) != 'true') { - await httpRequest.download( - urlPath: MyApi.images, - savePath: filePath, - onReceive: (count, total) { - streamController.add(DownloadEntity( - count: count / 1, - total: total / 1, - percent: (count / total) * 100, - )); - }, - ).then((value) async { - await LocalStorage.saveData( - key: MyConstants.downloadedImage, - value: 'true', - ); - }); - } - - try{ - if (LocalStorage.readData(key: MyConstants.extractedImage) != 'true') { - final File file = File(filePath); - final Directory directory = Directory('${StoragePath.documentDir.path}/'); - await ZipFile.extractToDirectory( - zipFile: file, - destinationDir: directory, - onExtracting: (zipEntry, progress) { - return ZipFileOperation.includeItem; - }, - ).then((value) async { - await Future.wait([ - LocalStorage.saveData( - key: MyConstants.extractedImage, - value: 'true', - ), - file.delete(recursive: true), - ]); - }); - } else { - streamController.add(DownloadEntity(percent: 50)); - await Future.delayed(Duration(milliseconds: 150)); - streamController.add(DownloadEntity(percent: 100)); - } - } catch (e){ - throw MyException(errorMessage: '$e'); - } - } - - @override - Stream loadingStream() => streamController.stream; -} diff --git a/lib/features/intro/data/repository_impl/intro_repository_impl.dart b/lib/features/intro/data/repository_impl/intro_repository_impl.dart deleted file mode 100644 index f6e5c0d..0000000 --- a/lib/features/intro/data/repository_impl/intro_repository_impl.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:flutter/foundation.dart'; -import 'package:hadi_hoda_flutter/core/error_handler/my_exception.dart'; -import 'package:hadi_hoda_flutter/core/params/no_params.dart'; -import 'package:hadi_hoda_flutter/core/utils/data_state.dart'; -import 'package:hadi_hoda_flutter/features/download/domain/entities/download_entity.dart'; -import 'package:hadi_hoda_flutter/features/intro/data/datasource/intro_datasource.dart'; -import 'package:hadi_hoda_flutter/features/intro/domain/repository/intro_repository.dart'; - -class IntroRepositoryImpl implements IIntroRepository { - final IIntroDatasource datasource; - - const IntroRepositoryImpl(this.datasource); - - @override - Future> getImages() async { - try { - await datasource.getImages(); - return DataState.success(NoParams()); - } on MyException catch (e) { - return DataState.error(e); - } catch (e) { - if (kDebugMode) { - rethrow; - } else { - return DataState.error(MyException(errorMessage: '$e')); - } - } - } - - @override - Stream loadingStream() { - return datasource.loadingStream(); - } -} diff --git a/lib/features/intro/domain/repository/intro_repository.dart b/lib/features/intro/domain/repository/intro_repository.dart deleted file mode 100644 index 4ee9181..0000000 --- a/lib/features/intro/domain/repository/intro_repository.dart +++ /dev/null @@ -1,9 +0,0 @@ -import 'package:hadi_hoda_flutter/core/error_handler/my_exception.dart'; -import 'package:hadi_hoda_flutter/core/params/no_params.dart'; -import 'package:hadi_hoda_flutter/core/utils/data_state.dart'; -import 'package:hadi_hoda_flutter/features/download/domain/entities/download_entity.dart'; - -abstract class IIntroRepository { - Future> getImages(); - Stream loadingStream(); -} diff --git a/lib/features/intro/domain/usecases/loading_stream_usecase.dart b/lib/features/intro/domain/usecases/loading_stream_usecase.dart deleted file mode 100644 index 1d81d89..0000000 --- a/lib/features/intro/domain/usecases/loading_stream_usecase.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:hadi_hoda_flutter/features/download/domain/entities/download_entity.dart'; -import 'package:hadi_hoda_flutter/features/intro/domain/repository/intro_repository.dart'; - -class LoadingStreamUseCase { - final IIntroRepository repository; - - const LoadingStreamUseCase(this.repository); - - Stream call() { - return repository.loadingStream(); - } -} diff --git a/lib/features/intro/presentation/bloc/intro_bloc.dart b/lib/features/intro/presentation/bloc/intro_bloc.dart index 0bc25e2..8ec0092 100644 --- a/lib/features/intro/presentation/bloc/intro_bloc.dart +++ b/lib/features/intro/presentation/bloc/intro_bloc.dart @@ -1,64 +1,44 @@ -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/constants/my_constants.dart'; -import 'package:hadi_hoda_flutter/core/params/no_params.dart'; +import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart'; import 'package:hadi_hoda_flutter/core/routers/my_routes.dart'; -import 'package:hadi_hoda_flutter/core/status/base_status.dart'; -import 'package:hadi_hoda_flutter/core/utils/context_provider.dart'; -import 'package:hadi_hoda_flutter/core/utils/local_storage.dart'; -import 'package:hadi_hoda_flutter/features/download/domain/entities/download_entity.dart'; -import 'package:hadi_hoda_flutter/features/intro/domain/usecases/get_images_usecase.dart'; -import 'package:hadi_hoda_flutter/features/intro/domain/usecases/loading_stream_usecase.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 IntroBloc extends Bloc { /// ------------constructor------------ - IntroBloc( - this._getImagesUseCase, - this._loadingStreamUseCase, - ) - : super(const IntroState()) { - on(_getImagesEvent); - loadingStream = _loadingStreamUseCase(); - } + IntroBloc() : super(const IntroState()); /// ------------UseCases------------ - final GetImagesUseCase _getImagesUseCase; - final LoadingStreamUseCase _loadingStreamUseCase; /// ------------Variables------------ - Stream loadingStream = Stream.empty(); /// ------------Controllers------------ /// ------------Functions------------ + Future _precacheAllImages(BuildContext context) async { + await Future.wait( + MyAssets.images.map( + (assetPath) => precacheImage(AssetImage(assetPath), context), + ), + ); + } - /// ------------Api Calls------------ - FutureOr _getImagesEvent( - GetImagesEvent event, - Emitter emit, - ) async { - emit(state.copyWith(getFilesStatus: BaseInit())); - await _getImagesUseCase(NoParams()).then((value) { - value.fold( - (data) async { - if(LocalStorage.readData(key: MyConstants.firstLanguagePage) != 'true'){ - ContextProvider.context.goNamed(Routes.languagePage); - } else { - await Future.delayed(Duration(milliseconds: 500), () { - if (ContextProvider.context.mounted) { - ContextProvider.context.goNamed(Routes.homePage); - } - }); - } - }, - (error) async { - emit(state.copyWith(getFilesStatus: BaseError(error.errorMessage))); - }, - ); - }); + Future goToHomePage(BuildContext context) async { + if (context.mounted) { + await _precacheAllImages(context); + } + + await Future.delayed( + Duration(seconds: 2), + () { + if (context.mounted) { + context.goNamed(Routes.homePage); + } + }, + ); } + + /// ------------Api Calls------------ } diff --git a/lib/features/intro/presentation/bloc/intro_event.dart b/lib/features/intro/presentation/bloc/intro_event.dart index 610637a..f9f7a91 100644 --- a/lib/features/intro/presentation/bloc/intro_event.dart +++ b/lib/features/intro/presentation/bloc/intro_event.dart @@ -1,4 +1,3 @@ sealed class IntroEvent { const IntroEvent(); } -class GetImagesEvent extends IntroEvent {} diff --git a/lib/features/intro/presentation/ui/intro_page.dart b/lib/features/intro/presentation/ui/intro_page.dart index 8d0d38b..fd3cdcf 100644 --- a/lib/features/intro/presentation/ui/intro_page.dart +++ b/lib/features/intro/presentation/ui/intro_page.dart @@ -1,20 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.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_spaces.dart'; -import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart'; -import 'package:hadi_hoda_flutter/core/status/base_status.dart'; -import 'package:hadi_hoda_flutter/core/utils/convert_size.dart'; -import 'package:hadi_hoda_flutter/core/utils/my_image.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/widgets/error/error_state.dart'; -import 'package:hadi_hoda_flutter/features/download/domain/entities/download_entity.dart'; +import 'package:hadi_hoda_flutter/core/widgets/animations/rotation_anim.dart'; +import 'package:hadi_hoda_flutter/core/widgets/images/my_image.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'; -import 'package:hadi_hoda_flutter/features/intro/presentation/ui/widgets/intro_loading_widget.dart'; class IntroPage extends StatefulWidget { const IntroPage({super.key}); @@ -27,9 +18,12 @@ class _IntroPageState extends State { @override void initState() { super.initState(); - context.read().add(GetImagesEvent()); + WidgetsBinding.instance.addPostFrameCallback((_) { + context.read().goToHomePage(context); + }); } + @override Widget build(BuildContext context) { return Scaffold( @@ -55,31 +49,12 @@ class _IntroPageState extends State { ), ), ), - child: BlocBuilder( - buildWhen: (previous, current) => - previous.getFilesStatus != current.getFilesStatus, - builder: (context, state) { - if (state.getFilesStatus is BaseError) { - return Padding( - padding: EdgeInsets.symmetric( - vertical: MediaQuery.viewPaddingOf(context).bottom + MySpaces.s16, - horizontal: 60, - ), - child: ErrorState( - onTap: () => context.read().add(GetImagesEvent()), - ), - ); - } else { - return Stack( - alignment: Alignment.center, - children: [ - _image(), - _text(context), - _loading(context), - ], - ); - } - } + child: Stack( + alignment: Alignment.center, + children: [ + _image(), + _loading(context), + ], ), ), ); @@ -92,39 +67,16 @@ class _IntroPageState extends State { ); } - Widget _text(BuildContext context) { - return PositionedDirectional( - bottom: 130, - child: Column( - spacing: MySpaces.s6, - children: [ - Text( - context.translate.please_wait, - style: Marhey.medium22.copyWith( - color: MyColors.white, - ), - ), - StreamBuilder( - initialData: DownloadEntity(), - stream: context.read().loadingStream, - builder: (context, snapshot) => Text( - '${context.translate.downloading_data} (${snapshot.data?.count.toMB ?? 0.0}mb / ${snapshot.data?.total.toMB ?? 0.0}mb)', - style: Marhey.medium12.copyWith( - color: MyColors.white, - ), - ), - ), - ], - ), - ); - } Positioned _loading(BuildContext context) { return Positioned( bottom: MediaQuery.viewPaddingOf(context).bottom + MySpaces.s16, - child: IntroLoadingWidget( - loadingStream: context.read().loadingStream, - ), + child: RotationAnim( + child: MyImage( + image: MyAssets.loading, + size: 70, + ), + ) ); } } diff --git a/lib/features/intro/presentation/ui/widgets/intro_loading_widget.dart b/lib/features/intro/presentation/ui/widgets/intro_loading_widget.dart deleted file mode 100644 index 12e4568..0000000 --- a/lib/features/intro/presentation/ui/widgets/intro_loading_widget.dart +++ /dev/null @@ -1,136 +0,0 @@ -import 'package:flutter/material.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/features/download/domain/entities/download_entity.dart'; - - -class IntroLoadingWidget extends StatelessWidget { - const IntroLoadingWidget({ - super.key, - this.loadingStream, - }); - - final Stream? loadingStream; - - @override - Widget build(BuildContext context) { - return ClipPath( - clipper: BubbleClip(), - child: Container( - width: 300, - height: 60, - padding: EdgeInsets.symmetric( - vertical: MySpaces.s4, - horizontal: MySpaces.s2, - ), - decoration: const BoxDecoration( - gradient: LinearGradient( - begin: Alignment(0, 1), // bottom - end: Alignment(0, -1), // top - colors: [ - Color(0xFFCADCFF), // #CADCFF - Colors.white, // #FFFFFF - ], - ), - ), - child: StreamBuilder( - initialData: DownloadEntity(), - stream: loadingStream, - builder: (context, snapshot) { - return Row( - children: [ - Expanded( - flex: 85, - child: ClipPath( - clipper: BubbleClip(), - child: AnimatedContainer( - duration: const Duration(milliseconds: 300), - padding: EdgeInsetsDirectional.only( - end: 260 - ((snapshot.data?.percent ?? 0) * 260 / 100), - ), - decoration: BoxDecoration( - color: Color(0xFF1F59BD).withValues(alpha: 0.25), - ), - child: ClipPath( - clipper: BubbleClip(), - child: Container( - decoration: BoxDecoration( - gradient: RadialGradient( - radius: 2, - colors: [ - Color(0xFFFFBD00), // #CADCFF - Color(0xFFFF772C), // #CADCFF - ], - ), - ), - ), - ), - ), - ), - ), - Expanded( - flex: 15, - child: Center( - child: Text( - '${snapshot.data?.percent?.toInt() ?? 0}%', - style: DinoKids.regular17.copyWith( - color: Color(0XFF6E83A8), - ), - ), - ), - ), - ], - ); - } - ), - ), - ); - } -} - -class BubbleClip extends CustomClipper { - @override - Path getClip(Size size) { - // Original SVG viewBox: 334 x 60 - const double w0 = 334.0; - const double h0 = 60.0; - final sx = size.width / w0; - final sy = size.height / h0; - - // SVG path: - // M9.82057 10.3597 - // C -1.70838 17.1589 -3.47995 44.4301 6.60447 53.1719 - // C 16.0075 61.291 305.076 61.9385 323.201 53.4956 - // C 341.326 45.0527 332.116 8.04571 324.829 5.7273 - // C 307.985 -2.06805 28.6539 -0.77294 9.82057 10.3597 - // Z - final p = Path() - ..moveTo(9.82057 * sx, 10.3597 * sy) - ..cubicTo( - -1.70838 * sx, 17.1589 * sy, - -3.47995 * sx, 44.4301 * sy, - 6.60447 * sx, 53.1719 * sy, - ) - ..cubicTo( - 16.0075 * sx, 61.291 * sy, - 305.076 * sx, 61.9385 * sy, - 323.201 * sx, 53.4956 * sy, - ) - ..cubicTo( - 341.326 * sx, 45.0527 * sy, - 332.116 * sx, 8.04571 * sy, - 324.829 * sx, 5.7273 * sy, - ) - ..cubicTo( - 307.985 * sx, -2.06805 * sy, - 28.6539 * sx, -0.77294 * sy, - 9.82057 * sx, 10.3597 * sy, - ) - ..close(); - - return p; - } - - @override - bool shouldReclip(covariant CustomClipper oldClipper) => false; -} diff --git a/lib/features/language/presentation/bloc/language_bloc.dart b/lib/features/language/presentation/bloc/language_bloc.dart index 364160a..f907683 100644 --- a/lib/features/language/presentation/bloc/language_bloc.dart +++ b/lib/features/language/presentation/bloc/language_bloc.dart @@ -49,7 +49,6 @@ class LanguageBloc extends Bloc { key: MyConstants.selectLanguage, value: state.selectedLang.code ?? 'fa', ), - LocalStorage.saveData(key: MyConstants.firstLanguagePage, value: 'true') ]); if (Directory( diff --git a/lib/features/language/presentation/ui/language_page.dart b/lib/features/language/presentation/ui/language_page.dart index cd5af65..957f1bc 100644 --- a/lib/features/language/presentation/ui/language_page.dart +++ b/lib/features/language/presentation/ui/language_page.dart @@ -4,10 +4,10 @@ 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/my_image.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/widgets/button/my_button.dart'; +import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; import 'package:hadi_hoda_flutter/features/language/presentation/bloc/language_bloc.dart'; import 'package:hadi_hoda_flutter/features/language/presentation/bloc/language_event.dart'; import 'package:hadi_hoda_flutter/features/language/presentation/bloc/language_state.dart'; diff --git a/lib/features/level/presentation/bloc/level_bloc.dart b/lib/features/level/presentation/bloc/level_bloc.dart index ef5cde4..7ec2351 100644 --- a/lib/features/level/presentation/bloc/level_bloc.dart +++ b/lib/features/level/presentation/bloc/level_bloc.dart @@ -26,6 +26,7 @@ class LevelBloc extends Bloc { on(_getLevelListEvent); on(_setCurrentLevelEvent); on(_startScrollEvent); + on(_chooseLevelEvent); } @override @@ -39,11 +40,11 @@ class LevelBloc extends Bloc { /// ------------Variables------------ final List bottomLocationList = [ - LevelLocation(bottom: -30, left: 30, index: 1), + LevelLocation(bottom: -20, left: 30, index: 1), LevelLocation(bottom: 50, left: 100, index: 2), LevelLocation(bottom: 150, left: 60, index: 3), LevelLocation(bottom: 210, left: 110, index: 4), - LevelLocation(bottom: 250, right: 60, index: 5), + LevelLocation(bottom: 260, right: 70, index: 5), LevelLocation(top: 170, right: 40, index: 6), LevelLocation(top: 70, right: 70, index: 7), LevelLocation(top: -20, right: 70, index: 8), @@ -148,7 +149,7 @@ class LevelBloc extends Bloc { await Future.delayed(const Duration(seconds: 1)); if (scrollController.hasClients) { - if(currentLevel < 9){ + if(currentLevel > 14){ scrollController.animateTo( scrollController.position.maxScrollExtent, duration: const Duration(milliseconds: 500), // Note: 500 seconds is very long. @@ -173,4 +174,11 @@ class LevelBloc extends Bloc { } add(GetLevelListEvent()); } + + FutureOr _chooseLevelEvent(ChooseLevelEvent event, + Emitter emit,) { + if (event.type != LevelType.unFinished) { + emit(state.copyWith(chooseLevel: event.level)); + } + } } diff --git a/lib/features/level/presentation/bloc/level_event.dart b/lib/features/level/presentation/bloc/level_event.dart index 88f0cca..818ed6f 100644 --- a/lib/features/level/presentation/bloc/level_event.dart +++ b/lib/features/level/presentation/bloc/level_event.dart @@ -1,4 +1,5 @@ import 'package:hadi_hoda_flutter/features/level/domain/entity/level_entity.dart'; +import 'package:hadi_hoda_flutter/features/level/presentation/ui/widgets/level_widget.dart'; sealed class LevelEvent { const LevelEvent(); @@ -9,5 +10,6 @@ class StartScrollEvent extends LevelEvent {} class SetCurrentLevelEvent extends LevelEvent {} class ChooseLevelEvent extends LevelEvent { final LevelEntity level; - const ChooseLevelEvent(this.level); + final LevelType type; + const ChooseLevelEvent(this.level, this.type); } diff --git a/lib/features/level/presentation/ui/level_page.dart b/lib/features/level/presentation/ui/level_page.dart index c9b774e..f0500ed 100644 --- a/lib/features/level/presentation/ui/level_page.dart +++ b/lib/features/level/presentation/ui/level_page.dart @@ -2,10 +2,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.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_image.dart'; import 'package:hadi_hoda_flutter/core/utils/screen_size.dart'; +import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; import 'package:hadi_hoda_flutter/features/level/domain/entity/level_entity.dart'; import 'package:hadi_hoda_flutter/features/level/presentation/bloc/level_bloc.dart'; +import 'package:hadi_hoda_flutter/features/level/presentation/bloc/level_event.dart'; import 'package:hadi_hoda_flutter/features/level/presentation/bloc/level_state.dart'; import 'package:hadi_hoda_flutter/features/level/presentation/ui/widgets/bottom_path.dart'; import 'package:hadi_hoda_flutter/features/level/presentation/ui/widgets/hint_level_widget.dart'; @@ -22,6 +23,7 @@ class LevelPage extends StatelessWidget { children: [ SingleChildScrollView( controller: context.read().scrollController, + reverse: true, child: Stack( alignment: Alignment.center, children: [ @@ -112,10 +114,15 @@ class LevelPage extends StatelessWidget { bottom: context.read().topLocationList[index].bottom, right: context.read().topLocationList[index].right, left: context.read().topLocationList[index].left, - child: LevelWidget( - level: context.read().top12LevelList[index], - type: context.read().getLevelType(index + 9), - onTap: (LevelEntity level) {}, + child: BlocBuilder( + builder: (context, state) => LevelWidget( + chooseLevel: state.chooseLevel, + level: context.read().top12LevelList[index], + type: context.read().getLevelType(index + 9), + onTap: (LevelEntity level, LevelType type) { + context.read().add(ChooseLevelEvent(level, type)); + }, + ), ), ), ), @@ -133,10 +140,7 @@ class LevelPage extends StatelessWidget { builder: (context, state) => Stack( clipBehavior: Clip.none, children: [ - BottomPath( - width: context.widthScreen * 0.75, - height: context.heightScreen * 0.65, - ), + BottomPath(), ...List.generate( context.read().bottom8LevelList.length, (index) => Positioned( @@ -144,10 +148,17 @@ class LevelPage extends StatelessWidget { bottom: context.read().bottomLocationList[index].bottom, right: context.read().bottomLocationList[index].right, left: context.read().bottomLocationList[index].left, - child: LevelWidget( - level: context.read().bottom8LevelList[index], - type: context.read().getLevelType(index + 1), - onTap: (LevelEntity level) {}, + child: BlocBuilder( + buildWhen: (previous, current) => + previous.chooseLevel?.id != current.chooseLevel?.id, + builder: (context, state) => LevelWidget( + chooseLevel: state.chooseLevel, + level: context.read().bottom8LevelList[index], + type: context.read().getLevelType(index + 1), + onTap: (LevelEntity level, LevelType type) { + context.read().add(ChooseLevelEvent(level, type)); + }, + ), ), ), ), diff --git a/lib/features/level/presentation/ui/widgets/bottom_path.dart b/lib/features/level/presentation/ui/widgets/bottom_path.dart index cb2d5a5..0d5e1b3 100644 --- a/lib/features/level/presentation/ui/widgets/bottom_path.dart +++ b/lib/features/level/presentation/ui/widgets/bottom_path.dart @@ -1,34 +1,28 @@ import 'package:flutter/material.dart'; +import 'package:hadi_hoda_flutter/common_ui/resources/my_colors.dart'; +import 'package:hadi_hoda_flutter/core/utils/screen_size.dart'; import 'package:path_drawing/path_drawing.dart'; class BottomPath extends StatelessWidget { - const BottomPath({ - super.key, - this.width = 500, - this.height = 1523, - this.color = Colors.white, - }); + const BottomPath({super.key}); - final double width; - final double height; - final Color color; @override Widget build(BuildContext context) { return CustomPaint( - painter: _Path(color), + painter: _Path(), size: Size( - width, - height, + context.widthScreen * 0.76, + context.heightScreen * 0.64, ), // or Size.infinite inside a parent with constraints ); } } class _Path extends CustomPainter { - _Path(this.color); + const _Path(); - final Color color; + final Color color = MyColors.white; // SVG viewBox static const double _vbW = 500; diff --git a/lib/features/level/presentation/ui/widgets/hint_level_widget.dart b/lib/features/level/presentation/ui/widgets/hint_level_widget.dart index c5a95bd..4c0c474 100644 --- a/lib/features/level/presentation/ui/widgets/hint_level_widget.dart +++ b/lib/features/level/presentation/ui/widgets/hint_level_widget.dart @@ -2,10 +2,10 @@ 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/common_ui/resources/my_text_style.dart'; -import 'package:hadi_hoda_flutter/core/utils/my_image.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/widgets/answer_box/styles/text_box.dart'; +import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; import 'package:hadi_hoda_flutter/features/level/domain/entity/level_entity.dart'; class HintLevelWidget extends StatelessWidget { diff --git a/lib/features/level/presentation/ui/widgets/level_widget.dart b/lib/features/level/presentation/ui/widgets/level_widget.dart index fea8e5a..c92a669 100644 --- a/lib/features/level/presentation/ui/widgets/level_widget.dart +++ b/lib/features/level/presentation/ui/widgets/level_widget.dart @@ -2,7 +2,7 @@ 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_colors.dart'; import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart'; -import 'package:hadi_hoda_flutter/core/utils/my_image.dart'; +import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; import 'package:hadi_hoda_flutter/features/level/domain/entity/level_entity.dart'; enum LevelType { @@ -21,18 +21,20 @@ class LevelWidget extends StatelessWidget { const LevelWidget({ super.key, required this.level, - this.type, + required this.type, + required this.chooseLevel, this.onTap, }); - final LevelType? type; + final LevelType type; final LevelEntity level; - final Function(LevelEntity level)? onTap; + final LevelEntity? chooseLevel; + final Function(LevelEntity level, LevelType type)? onTap; @override Widget build(BuildContext context) { return InkWell( - onTap: () => onTap?.call(level), + onTap: () => onTap?.call(level, type), child: Stack( alignment: Alignment.topCenter, clipBehavior: Clip.none, @@ -51,7 +53,7 @@ class LevelWidget extends StatelessWidget { ], ), ), - if(type == LevelType.current) + if(level.id == chooseLevel?.id) Positioned( top: -20, child: MyImage( diff --git a/lib/features/question/presentation/bloc/question_bloc.dart b/lib/features/question/presentation/bloc/question_bloc.dart index e33c3bb..eda94c4 100644 --- a/lib/features/question/presentation/bloc/question_bloc.dart +++ b/lib/features/question/presentation/bloc/question_bloc.dart @@ -126,13 +126,15 @@ class QuestionBloc extends Bloc { ); if (state.currentQuestion?.order == state.levelEntity?.questions?.length) { - int currentLevel = int.parse( + int currentLevel = int.parse( LocalStorage.readData(key: MyConstants.currentLevel) ?? '1'); - ++currentLevel; - await LocalStorage.saveData( - key: MyConstants.currentLevel, - value: '$currentLevel', - ); + if (state.levelEntity?.order == currentLevel) { + ++currentLevel; + await LocalStorage.saveData( + key: MyConstants.currentLevel, + value: '$currentLevel', + ); + } } else { await playVoice(); } diff --git a/lib/features/question/presentation/ui/question_page.dart b/lib/features/question/presentation/ui/question_page.dart index 746c25c..34b97ec 100644 --- a/lib/features/question/presentation/ui/question_page.dart +++ b/lib/features/question/presentation/ui/question_page.dart @@ -44,6 +44,7 @@ class QuestionPage extends StatelessWidget { ), ), child: SafeArea( + bottom: false, child: Padding( padding: const EdgeInsets.symmetric(horizontal: MySpaces.s16), child: Column( diff --git a/lib/features/question/presentation/ui/screens/diamond_screen.dart b/lib/features/question/presentation/ui/screens/diamond_screen.dart index 4cd796c..66e02a9 100644 --- a/lib/features/question/presentation/ui/screens/diamond_screen.dart +++ b/lib/features/question/presentation/ui/screens/diamond_screen.dart @@ -4,13 +4,14 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.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_spaces.dart'; import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart'; import 'package:hadi_hoda_flutter/core/utils/gap.dart'; -import 'package:hadi_hoda_flutter/core/utils/my_image.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/widgets/button/enum/button_type.dart'; import 'package:hadi_hoda_flutter/core/widgets/button/my_button.dart'; +import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; import 'package:hadi_hoda_flutter/features/question/presentation/bloc/question_bloc.dart'; import 'package:hadi_hoda_flutter/features/question/presentation/bloc/question_event.dart'; @@ -128,37 +129,42 @@ class DiamondScreen extends StatelessWidget { ); } - Row _btns(BuildContext context) { - return Row( - children: [ - Expanded( - child: InkWell( - onTap: () => context.read().goToLevelPage(context: context), - child: Stack( - alignment: Alignment.center, - children: [ - MyImage(image: MyAssets.button3, size: 84), - Positioned( - top: 10, - child: Text( - context.translate.view_map, - style: DinoKids.regular35.copyWith( - color: Color(0XFFD93D16), + Widget _btns(BuildContext context) { + return Padding( + padding: EdgeInsets.only( + bottom: MediaQuery.viewPaddingOf(context).bottom + MySpaces.s16, + ), + child: Row( + children: [ + Expanded( + child: InkWell( + onTap: () => context.read().goToLevelPage(context: context), + child: Stack( + alignment: Alignment.center, + children: [ + MyImage(image: MyAssets.button3, size: 84), + Positioned( + top: 10, + child: Text( + context.translate.view_map, + style: DinoKids.regular35.copyWith( + color: Color(0XFFD93D16), + ), ), ), - ), - ], + ], + ), ), ), - ), - Expanded( - child: MyButton( - onTap: () => context.read().add(GetNextLevelEvent()), - title: context.translate.go_next, - type: ButtonType.type2, + Expanded( + child: MyButton( + onTap: () => context.read().add(GetNextLevelEvent()), + title: context.translate.go_next, + type: ButtonType.type2, + ), ), - ), - ], + ], + ), ); } } diff --git a/lib/features/question/presentation/ui/screens/question_screen.dart b/lib/features/question/presentation/ui/screens/question_screen.dart index c4ec545..acd10d9 100644 --- a/lib/features/question/presentation/ui/screens/question_screen.dart +++ b/lib/features/question/presentation/ui/screens/question_screen.dart @@ -5,9 +5,9 @@ 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/gap.dart'; -import 'package:hadi_hoda_flutter/core/utils/my_image.dart'; import 'package:hadi_hoda_flutter/core/utils/my_localization.dart'; import 'package:hadi_hoda_flutter/core/widgets/answer_box/answer_box.dart'; +import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; import 'package:hadi_hoda_flutter/core/widgets/showcase/question_showcase.dart'; import 'package:hadi_hoda_flutter/features/question/domain/entity/answer_entity.dart'; import 'package:hadi_hoda_flutter/features/question/presentation/bloc/question_bloc.dart'; @@ -116,25 +116,39 @@ class QuestionScreen extends StatelessWidget { builder: (context, state) => Stack( clipBehavior: Clip.none, children: [ - if(state.correctAnswer == false) - PositionedDirectional( - start: -100, - top: -10, + PositionedDirectional( + start: -100, + top: -10, + child: AnimatedOpacity( + opacity: state.correctAnswer == false ? 1 : 0, + duration: Duration(milliseconds: 200), child: LeftBlob(), ), - MyImage( - image: state.correctAnswer == true - ? MyAssets.happyPersons - : MyAssets.persons, - fit: BoxFit.contain, - size: 110, ), - if(state.correctAnswer == false) - PositionedDirectional( - top: -30, - end: -90, + AnimatedCrossFade( + duration: Duration(milliseconds: 200), + reverseDuration: Duration(milliseconds: 200), + crossFadeState: state.correctAnswer == true ? CrossFadeState + .showSecond : CrossFadeState.showFirst, + firstChild: MyImage( + image: MyAssets.persons, + fit: BoxFit.contain, + ), + secondChild: MyImage( + image: MyAssets.happyPersons, + fit: BoxFit.contain, + size: 110, + ), + ), + PositionedDirectional( + top: -30, + end: -90, + child: AnimatedOpacity( + opacity: state.correctAnswer == false ? 1 : 0, + duration: Duration(milliseconds: 200), child: RightBlob(), ), + ), ], ), ), diff --git a/lib/features/question/presentation/ui/widgets/glassy_button.dart b/lib/features/question/presentation/ui/widgets/glassy_button.dart index b3beb7b..211b00b 100644 --- a/lib/features/question/presentation/ui/widgets/glassy_button.dart +++ b/lib/features/question/presentation/ui/widgets/glassy_button.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:hadi_hoda_flutter/common_ui/resources/my_spaces.dart'; -import 'package:hadi_hoda_flutter/core/utils/my_image.dart'; +import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; class GlassyButton extends StatelessWidget { const GlassyButton({super.key, required this.image, this.onTap}); diff --git a/lib/features/question/presentation/ui/widgets/left_blob.dart b/lib/features/question/presentation/ui/widgets/left_blob.dart index f09256b..3f53a61 100644 --- a/lib/features/question/presentation/ui/widgets/left_blob.dart +++ b/lib/features/question/presentation/ui/widgets/left_blob.dart @@ -1,8 +1,8 @@ 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_text_style.dart'; -import 'package:hadi_hoda_flutter/core/utils/my_image.dart'; import 'package:hadi_hoda_flutter/core/utils/my_localization.dart'; +import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; class LeftBlob extends StatelessWidget { const LeftBlob({super.key}); diff --git a/lib/features/question/presentation/ui/widgets/question_stepper.dart b/lib/features/question/presentation/ui/widgets/question_stepper.dart index bcb4a39..d7408b4 100644 --- a/lib/features/question/presentation/ui/widgets/question_stepper.dart +++ b/lib/features/question/presentation/ui/widgets/question_stepper.dart @@ -1,7 +1,7 @@ import 'package:easy_stepper/easy_stepper.dart'; import 'package:flutter/material.dart'; import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart'; -import 'package:hadi_hoda_flutter/core/utils/my_image.dart'; +import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; class QuestionStepper extends StatelessWidget { const QuestionStepper({super.key, required this.length ,required this.currentStep}); diff --git a/lib/features/question/presentation/ui/widgets/right_blob.dart b/lib/features/question/presentation/ui/widgets/right_blob.dart index 03f4268..168395b 100644 --- a/lib/features/question/presentation/ui/widgets/right_blob.dart +++ b/lib/features/question/presentation/ui/widgets/right_blob.dart @@ -1,8 +1,8 @@ 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_text_style.dart'; -import 'package:hadi_hoda_flutter/core/utils/my_image.dart'; import 'package:hadi_hoda_flutter/core/utils/my_localization.dart'; +import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; class RightBlob extends StatelessWidget { const RightBlob({super.key}); diff --git a/lib/init_bindings.dart b/lib/init_bindings.dart index 4741241..931d43b 100644 --- a/lib/init_bindings.dart +++ b/lib/init_bindings.dart @@ -9,13 +9,9 @@ import 'package:hadi_hoda_flutter/features/download/data/datasource/download_dat import 'package:hadi_hoda_flutter/features/download/data/repository_impl/download_repository_impl.dart'; import 'package:hadi_hoda_flutter/features/download/domain/repository/download_repository.dart'; import 'package:hadi_hoda_flutter/features/download/domain/usecases/get_audios_usecase.dart'; -import 'package:hadi_hoda_flutter/features/download/domain/usecases/loading_stream_audio_usecase.dart'; +import 'package:hadi_hoda_flutter/features/download/domain/usecases/get_images_usecase.dart'; +import 'package:hadi_hoda_flutter/features/download/domain/usecases/loading_stream_usecase.dart'; import 'package:hadi_hoda_flutter/features/download/domain/usecases/save_levels_usecase.dart'; -import 'package:hadi_hoda_flutter/features/intro/data/datasource/intro_datasource.dart'; -import 'package:hadi_hoda_flutter/features/intro/data/repository_impl/intro_repository_impl.dart'; -import 'package:hadi_hoda_flutter/features/intro/domain/repository/intro_repository.dart'; -import 'package:hadi_hoda_flutter/features/intro/domain/usecases/get_images_usecase.dart'; -import 'package:hadi_hoda_flutter/features/intro/domain/usecases/loading_stream_usecase.dart'; import 'package:hadi_hoda_flutter/features/level/data/datasource/level_datasource.dart'; import 'package:hadi_hoda_flutter/features/level/data/repository_impl/level_repository_impl.dart'; import 'package:hadi_hoda_flutter/features/level/domain/entity/level_entity.dart'; @@ -50,17 +46,14 @@ void initBindings() { locator.registerLazySingleton(() => GetSampleUseCase(locator())); /// Intro Feature - locator.registerLazySingleton(() => IntroDatasourceImpl(locator())); - locator.registerLazySingleton(() => IntroRepositoryImpl(locator())); - locator.registerLazySingleton(() => GetImagesUseCase(locator())); - locator.registerLazySingleton(() => LoadingStreamUseCase(locator())); /// Download Feature locator.registerLazySingleton(() => DownloadDatasourceImpl(locator())); locator.registerLazySingleton(() => DownloadRepositoryImpl(locator())); + locator.registerLazySingleton(() => GetImagesUseCase(locator())); locator.registerLazySingleton(() => GetAudiosUseCase(locator())); locator.registerLazySingleton(() => SaveLevelsUseCase(locator())); - locator.registerLazySingleton(() => LoadingStreamAudioUseCase(locator())); + locator.registerLazySingleton(() => LoadingStreamUseCase(locator())); /// Language Feature diff --git a/pubspec.lock b/pubspec.lock index 1b61d45..f8bbe92 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -299,14 +299,6 @@ packages: description: flutter source: sdk version: "0.0.0" - flutter_svg: - dependency: "direct main" - description: - name: flutter_svg - sha256: b9c2ad5872518a27507ab432d1fb97e8813b05f0fc693f9d40fad06d073e0678 - url: "https://pub.dev" - source: hosted - version: "2.2.1" flutter_test: dependency: "direct dev" description: flutter @@ -899,7 +891,7 @@ packages: source: hosted version: "4.5.1" vector_graphics: - dependency: transitive + dependency: "direct main" description: name: vector_graphics sha256: a4f059dc26fc8295b5921376600a194c4ec7d55e72f2fe4c7d2831e103d461e6 @@ -915,7 +907,7 @@ packages: source: hosted version: "1.1.13" vector_graphics_compiler: - dependency: transitive + dependency: "direct dev" description: name: vector_graphics_compiler sha256: d354a7ec6931e6047785f4db12a1f61ec3d43b207fc0790f863818543f8ff0dc diff --git a/pubspec.yaml b/pubspec.yaml index 84f89c0..52ef959 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -18,7 +18,6 @@ dependencies: flutter_bloc: ^9.1.1 flutter_localizations: sdk: flutter - flutter_svg: ^2.2.1 get_it: ^8.2.0 go_router: ^16.1.0 hive: ^2.2.3 @@ -29,6 +28,7 @@ dependencies: pretty_dio_logger: ^1.4.0 shared_preferences: ^2.5.3 showcaseview: ^4.0.1 + vector_graphics: ^1.1.19 dev_dependencies: flutter_test: @@ -36,6 +36,7 @@ dev_dependencies: flutter_lints: ^5.0.0 hive_generator: ^2.0.1 build_runner: ^2.4.13 + vector_graphics_compiler: ^1.1.19 flutter: uses-material-design: true @@ -44,6 +45,9 @@ flutter: assets: - assets/fonts/ - assets/images/ + - path: assets/svg/ + transformers: + - package: vector_graphics_compiler fonts: