diff --git a/lib/core/constants/my_constants.dart b/lib/core/constants/my_constants.dart index 76b8d54..09e197e 100644 --- a/lib/core/constants/my_constants.dart +++ b/lib/core/constants/my_constants.dart @@ -10,4 +10,5 @@ class MyConstants { static const String extractCompleted = 'EXTRACT_COMPLETED'; static const String selectLanguage = 'SELECT_LANGUAGE'; static const String firstLanguagePage = 'FIRST_LANGUAGE_PAGE'; + static const String currentLevel = 'CURRENT_LEVEL'; } \ No newline at end of file diff --git a/lib/core/routers/my_routes.dart b/lib/core/routers/my_routes.dart index 13f5e6b..2c5c202 100644 --- a/lib/core/routers/my_routes.dart +++ b/lib/core/routers/my_routes.dart @@ -52,7 +52,7 @@ GoRouter get appPages => GoRouter( name: Routes.homePage, path: Routes.homePage, builder: (context, state) => BlocProvider( - create: (context) => HomeBloc(locator()), + create: (context) => HomeBloc(), child: const HomePage(), ), ), 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 a982547..ec274f3 100644 --- a/lib/core/widgets/about_us_dialog/about_us_dialog.dart +++ b/lib/core/widgets/about_us_dialog/about_us_dialog.dart @@ -58,7 +58,7 @@ class AboutUsDialog extends StatelessWidget { ), MyImage( image: MyAssets.newHorizon, - size: 70, + size: 45, ), MyImage( image: MyAssets.khadijeLogo, diff --git a/lib/features/home/data/datasource/home_datasource.dart b/lib/features/home/data/datasource/home_datasource.dart deleted file mode 100644 index 17db1cf..0000000 --- a/lib/features/home/data/datasource/home_datasource.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:hadi_hoda_flutter/core/constants/my_api.dart'; -import 'package:hadi_hoda_flutter/core/network/http_request.dart'; -import 'package:hadi_hoda_flutter/core/params/home_params.dart'; -import 'package:hadi_hoda_flutter/core/response/base_response.dart'; -import 'package:hadi_hoda_flutter/features/home/data/model/home_model.dart'; -import 'package:hadi_hoda_flutter/features/home/domain/entity/home_entity.dart'; - -abstract class IHomeDatasource { - Future getData({required HomeParams params}); -} - -class HomeDatasourceImpl implements IHomeDatasource { - final IHttpRequest httpRequest; - - const HomeDatasourceImpl(this.httpRequest); - - @override - Future getData({required HomeParams params}) async { - final response = await httpRequest.get( - path: MyApi.baseUrl, - ); - - return BaseResponse.getData( - response?['data'], - (json) => HomeModel.fromJson(json), - ); - } -} diff --git a/lib/features/home/data/model/home_model.dart b/lib/features/home/data/model/home_model.dart deleted file mode 100644 index c63431f..0000000 --- a/lib/features/home/data/model/home_model.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:hadi_hoda_flutter/features/home/domain/entity/home_entity.dart'; - -class HomeModel extends HomeEntity { - const HomeModel({ - super.id, - }); - - factory HomeModel.fromJson(Map json) { - return HomeModel( - id: json['id'], - ); - } -} diff --git a/lib/features/home/data/repository_impl/home_repository_impl.dart b/lib/features/home/data/repository_impl/home_repository_impl.dart deleted file mode 100644 index 594969b..0000000 --- a/lib/features/home/data/repository_impl/home_repository_impl.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:hadi_hoda_flutter/core/params/home_params.dart'; -import 'package:flutter/foundation.dart'; -import 'package:hadi_hoda_flutter/core/error_handler/my_exception.dart'; -import 'package:hadi_hoda_flutter/core/utils/data_state.dart'; -import 'package:hadi_hoda_flutter/features/home/data/datasource/home_datasource.dart'; -import 'package:hadi_hoda_flutter/features/home/domain/entity/home_entity.dart'; -import 'package:hadi_hoda_flutter/features/home/domain/repository/home_repository.dart'; - -class HomeRepositoryImpl implements IHomeRepository { - final IHomeDatasource datasource; - - const HomeRepositoryImpl(this.datasource); - - @override - Future> getData({required HomeParams params}) async { - try { - final HomeEntity response = await datasource.getData(params: params); - return DataState.success(response); - } on MyException catch (e) { - return DataState.error(e); - } catch (e) { - if (kDebugMode) { - rethrow; - } else { - return DataState.error(MyException(errorMessage: '$e')); - } - } - } -} diff --git a/lib/features/home/domain/entity/home_entity.dart b/lib/features/home/domain/entity/home_entity.dart deleted file mode 100644 index 582723c..0000000 --- a/lib/features/home/domain/entity/home_entity.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:equatable/equatable.dart'; - -class HomeEntity extends Equatable { - final int? id; - - const HomeEntity({ - this.id, - }); - - @override - List get props => [ - id, - ]; -} diff --git a/lib/features/home/domain/repository/home_repository.dart b/lib/features/home/domain/repository/home_repository.dart deleted file mode 100644 index 81ad27c..0000000 --- a/lib/features/home/domain/repository/home_repository.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:hadi_hoda_flutter/core/error_handler/my_exception.dart'; -import 'package:hadi_hoda_flutter/core/params/home_params.dart'; -import 'package:hadi_hoda_flutter/core/utils/data_state.dart'; -import 'package:hadi_hoda_flutter/features/home/domain/entity/home_entity.dart'; - -abstract class IHomeRepository { - Future> getData({required HomeParams params}); -} diff --git a/lib/features/home/domain/usecases/get_home_usecase.dart b/lib/features/home/domain/usecases/get_home_usecase.dart deleted file mode 100644 index cbb629d..0000000 --- a/lib/features/home/domain/usecases/get_home_usecase.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:hadi_hoda_flutter/core/error_handler/my_exception.dart'; -import 'package:hadi_hoda_flutter/core/params/home_params.dart'; -import 'package:hadi_hoda_flutter/core/usecase/usecase.dart'; -import 'package:hadi_hoda_flutter/core/utils/data_state.dart'; -import 'package:hadi_hoda_flutter/features/home/domain/entity/home_entity.dart'; -import 'package:hadi_hoda_flutter/features/home/domain/repository/home_repository.dart'; - -class GetHomeUseCase implements UseCase { - final IHomeRepository repository; - - const GetHomeUseCase(this.repository); - - @override - Future> call(HomeParams params) { - return repository.getData(params: params); - } -} diff --git a/lib/features/home/presentation/bloc/home_bloc.dart b/lib/features/home/presentation/bloc/home_bloc.dart index 7360c97..342cc3c 100644 --- a/lib/features/home/presentation/bloc/home_bloc.dart +++ b/lib/features/home/presentation/bloc/home_bloc.dart @@ -3,22 +3,17 @@ 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/status/base_status.dart'; -import 'package:hadi_hoda_flutter/features/home/domain/entity/home_entity.dart'; -import 'package:hadi_hoda_flutter/features/home/domain/usecases/get_home_usecase.dart'; +import 'package:hadi_hoda_flutter/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'; class HomeBloc extends Bloc { /// ------------constructor------------ - HomeBloc( - this._getHomeUseCase, - ) : super(const HomeState()) { + HomeBloc() : super(const HomeState()) { on(_getHomeEvent); } /// ------------UseCases------------ - final GetHomeUseCase _getHomeUseCase; /// ------------Variables------------ @@ -33,19 +28,10 @@ class HomeBloc extends Bloc { context.pushNamed(Routes.languagePage); } - /// ------------Api Calls------------ - FutureOr _getHomeEvent(event, emit) async { - await _getHomeUseCase(event.homeParams).then( - (value) { - value.fold( - (data) { - emit(state.copyWith(getHomeStatus: BaseComplete(data))); - }, - (error) { - emit(state.copyWith(getHomeStatus: BaseError(error.errorMessage))); - }, - ); - }, - ); + void showAboutUs(BuildContext context){ + showAboutUsDialog(context: context); } + + /// ------------Api Calls------------ + FutureOr _getHomeEvent(event, emit) async {} } diff --git a/lib/features/home/presentation/ui/home_page.dart b/lib/features/home/presentation/ui/home_page.dart index 17472af..3234e84 100644 --- a/lib/features/home/presentation/ui/home_page.dart +++ b/lib/features/home/presentation/ui/home_page.dart @@ -4,7 +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/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/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/features/home/presentation/bloc/home_bloc.dart'; class HomePage extends StatelessWidget { @@ -77,17 +80,17 @@ class HomePage extends StatelessWidget { size: checkSize(context: context, tablet: 120), ), ), + MyButton( + onTap: () => context.read().goToLevelPage(context), + type: ButtonType.type2, + title: context.translate.start, + ), InkWell( + onTap: () => context.read().showAboutUs(context), child: MyImage( - image: MyAssets.button, - size: checkSize(context: context, mobile: 90, tablet: 160), + image: MyAssets.theme, + size: checkSize(context: context, tablet: 120), ), - onTap: () => - BlocProvider.of(context).goToLevelPage(context), - ), - MyImage( - image: MyAssets.theme, - size: checkSize(context: context, tablet: 120), ), ], ), diff --git a/lib/features/level/data/datasource/level_datasource.dart b/lib/features/level/data/datasource/level_datasource.dart index 1921cc1..e3c75fe 100644 --- a/lib/features/level/data/datasource/level_datasource.dart +++ b/lib/features/level/data/datasource/level_datasource.dart @@ -1,7 +1,9 @@ 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/params/level_params.dart'; +import 'package:hadi_hoda_flutter/core/utils/local_storage.dart'; import 'package:hadi_hoda_flutter/features/level/domain/entity/level_entity.dart'; +import 'package:hadi_hoda_flutter/features/level/domain/entity/total_data_entity.dart'; import 'package:hive/hive.dart'; abstract class ILevelDatasource { @@ -10,14 +12,19 @@ abstract class ILevelDatasource { /// Local class LocalLevelDatasourceImpl implements ILevelDatasource { - const LocalLevelDatasourceImpl(); @override Future> getLevels({required LevelParams params}) async { try { - final Box levelBox = Hive.box(MyConstants.levelBox); - return levelBox.values.toList(); + final String selectedLanguage = LocalStorage.readData( + key: MyConstants.selectLanguage); + final Box levelBox = Hive.box(MyConstants.levelBox); + final TotalDataEntity findData = levelBox.values.singleWhere((e) => + e.code == selectedLanguage, + orElse: () => TotalDataEntity(), + ); + return findData.levels ?? []; } catch (_) { throw MyException(errorMessage: 'Operation Failed'); } diff --git a/lib/features/level/presentation/bloc/level_bloc.dart b/lib/features/level/presentation/bloc/level_bloc.dart index ed56711..2cb4c92 100644 --- a/lib/features/level/presentation/bloc/level_bloc.dart +++ b/lib/features/level/presentation/bloc/level_bloc.dart @@ -2,14 +2,17 @@ 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/level_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/local_storage.dart'; import 'package:hadi_hoda_flutter/features/level/domain/entity/level_entity.dart'; import 'package:hadi_hoda_flutter/features/level/domain/entity/level_location.dart'; import 'package:hadi_hoda_flutter/features/level/domain/usecases/get_levels_usecase.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/level_widget.dart'; class LevelBloc extends Bloc { /// ------------constructor------------ @@ -17,6 +20,7 @@ class LevelBloc extends Bloc { this._getLeveslUseCase, ) : super(const LevelState()) { on(_getLevelListEvent); + on(_startScrollEvent); } @override @@ -63,7 +67,6 @@ class LevelBloc extends Bloc { final ScrollController scrollController = ScrollController(); /// ------------Functions------------ - void goToQuestionPage(BuildContext context, LevelEntity level){ context.pushNamed( Routes.questionPage, @@ -73,6 +76,25 @@ class LevelBloc extends Bloc { ); } + void goToHomePage(BuildContext context){ + context.pop(); + } + + LevelType getLevelType(int index) { + final int currentLevel = int.parse(LocalStorage + .readData(key: MyConstants.currentLevel) + .isEmpty ? '1' : LocalStorage + .readData(key: MyConstants.currentLevel)); + + if (index < currentLevel) { + return LevelType.finished; + } else if (index == currentLevel) { + return LevelType.current; + } else { + return LevelType.unFinished; + } + } + /// ------------Api Calls------------ FutureOr _getLevelListEvent(GetLevelListEvent event, Emitter emit) async { @@ -87,15 +109,37 @@ class LevelBloc extends Bloc { getLevelStatus: const BaseComplete(''), chooseLevel: data.first, )); - await Future.delayed(Duration(milliseconds: 500)); - scrollController.animateTo( - scrollController.position.maxScrollExtent, - duration: Duration(seconds: 1), - curve: Curves.easeInOut, - ); + add(StartScrollEvent()); }, (error) {}, ); }); } + + FutureOr _startScrollEvent( + StartScrollEvent event, + Emitter emit, + ) async { + final int currentLevel = int.parse(LocalStorage + .readData(key: MyConstants.currentLevel) + .isEmpty ? '1' : LocalStorage + .readData(key: MyConstants.currentLevel)); + + await Future.delayed(const Duration(seconds: 1)); + if (scrollController.hasClients) { + if(currentLevel < 9){ + scrollController.animateTo( + scrollController.position.maxScrollExtent, + duration: const Duration(milliseconds: 500), // Note: 500 seconds is very long. + curve: Curves.easeInOut, + ); + } else if( currentLevel > 8 && currentLevel < 14){ + scrollController.animateTo( + scrollController.position.maxScrollExtent / 2, + duration: const Duration(milliseconds: 500), // Note: 500 seconds is very long. + curve: Curves.easeInOut, + ); + } + } + } } diff --git a/lib/features/level/presentation/bloc/level_event.dart b/lib/features/level/presentation/bloc/level_event.dart index 6f9020c..d081e54 100644 --- a/lib/features/level/presentation/bloc/level_event.dart +++ b/lib/features/level/presentation/bloc/level_event.dart @@ -5,6 +5,7 @@ sealed class LevelEvent { } class GetLevelListEvent extends LevelEvent {} +class StartScrollEvent extends LevelEvent {} class ChooseLevelEvent extends LevelEvent { final LevelEntity level; const ChooseLevelEvent(this.level); diff --git a/lib/features/level/presentation/ui/level_page.dart b/lib/features/level/presentation/ui/level_page.dart index 9a9673d..d971070 100644 --- a/lib/features/level/presentation/ui/level_page.dart +++ b/lib/features/level/presentation/ui/level_page.dart @@ -26,7 +26,7 @@ class LevelPage extends StatelessWidget { alignment: Alignment.center, children: [ _background(), - // _topPath(context), + _topPath(context), _bottomPath(context), ], ), @@ -47,7 +47,7 @@ class LevelPage extends StatelessWidget { return Positioned( bottom: MediaQuery .viewPaddingOf(context) - .bottom + 10, + .bottom + MySpaces.s10, right: MySpaces.s16, left: MySpaces.s16, child: HintLevelWidget( @@ -71,8 +71,11 @@ class LevelPage extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - MyImage( - image: MyAssets.homeButton, + InkWell( + onTap: () => context.read().goToHomePage(context), + child: MyImage( + image: MyAssets.homeButton, + ), ), MyImage( image: MyAssets.musicOn, @@ -107,9 +110,8 @@ class LevelPage extends StatelessWidget { child: LevelWidget( index: context.read().topLocationList[index].index ?? 0, level: context.read().top12LevelList[index], - onTap: (LevelEntity level) { - - }, + type: context.read().getLevelType(index + 9), + onTap: (LevelEntity level) {}, ), ), ), @@ -141,10 +143,8 @@ class LevelPage extends StatelessWidget { child: LevelWidget( index: context.read().bottomLocationList[index].index ?? 0, level: context.read().bottom8LevelList[index], - type: index == 0 ? LevelType.current : LevelType.unFinished, - onTap: (LevelEntity level) { - - }, + type: context.read().getLevelType(index + 1), + onTap: (LevelEntity level) {}, ), ), ), diff --git a/lib/init_bindings.dart b/lib/init_bindings.dart index 997baae..be6cedf 100644 --- a/lib/init_bindings.dart +++ b/lib/init_bindings.dart @@ -3,10 +3,6 @@ import 'dart:io'; import 'package:hadi_hoda_flutter/core/constants/my_constants.dart'; import 'package:hadi_hoda_flutter/core/network/http_request.dart'; import 'package:hadi_hoda_flutter/core/network/http_request_impl.dart'; -import 'package:hadi_hoda_flutter/features/home/data/datasource/home_datasource.dart'; -import 'package:hadi_hoda_flutter/features/home/data/repository_impl/home_repository_impl.dart'; -import 'package:hadi_hoda_flutter/features/home/domain/repository/home_repository.dart'; -import 'package:hadi_hoda_flutter/features/home/domain/usecases/get_home_usecase.dart'; import 'package:hadi_hoda_flutter/features/intro/data/datasource/intro_datasource.dart'; import 'package:hadi_hoda_flutter/features/intro/data/repository_impl/intro_repository_impl.dart'; import 'package:hadi_hoda_flutter/features/intro/domain/repository/intro_repository.dart'; @@ -55,9 +51,6 @@ void initBindings() { /// Language Feature /// Home Feature - locator.registerLazySingleton(() => HomeDatasourceImpl(locator())); - locator.registerLazySingleton(() => HomeRepositoryImpl(locator())); - locator.registerLazySingleton(() => GetHomeUseCase(locator())); /// Question Feature locator.registerLazySingleton(() => QuestionDatasourceImpl(locator())); diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 66f926e..efe6555 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -8,5 +8,6 @@ "downloading_data": "Downloading initial data", "lost_connection": "Lost connection!", "try_again": "Try Again", - "connected_to_internet": "You must be connected to the internet to download the initial game data." + "connected_to_internet": "You must be connected to the internet to download the initial game data.", + "start": "Start" } \ No newline at end of file diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 7d3e5a1..8edc5d4 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -153,6 +153,12 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'You must be connected to the internet to download the initial game data.'** String get connected_to_internet; + + /// No description provided for @start. + /// + /// In en, this message translates to: + /// **'Start'** + String get start; } class _AppLocalizationsDelegate diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 521588d..d43de00 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -39,4 +39,7 @@ class AppLocalizationsEn extends AppLocalizations { @override String get connected_to_internet => 'You must be connected to the internet to download the initial game data.'; + + @override + String get start => 'Start'; }