From f71f66125c7703d4348a5115a9eaf9a8c89f525e Mon Sep 17 00:00:00 2001 From: AmirrezaChegini Date: Fri, 3 Oct 2025 01:08:41 +0330 Subject: [PATCH 1/3] add: base language feature --- lib/core/params/language_params.dart | 13 ++++++ lib/core/routers/my_routes.dart | 13 +++++- .../data/datasource/language_datasource.dart | 28 +++++++++++++ .../language/data/model/language_model.dart | 13 ++++++ .../language_repository_impl.dart | 29 +++++++++++++ .../domain/entity/language_entity.dart | 14 +++++++ .../repository/language_repository.dart | 8 ++++ .../domain/usecases/get_language_usecase.dart | 17 ++++++++ .../presentation/bloc/language_bloc.dart | 41 +++++++++++++++++++ .../presentation/bloc/language_event.dart | 5 +++ .../presentation/bloc/language_state.dart | 15 +++++++ .../presentation/ui/language_page.dart | 10 +++++ lib/init_bindings.dart | 9 ++++ 13 files changed, 214 insertions(+), 1 deletion(-) create mode 100644 lib/core/params/language_params.dart create mode 100644 lib/features/language/data/datasource/language_datasource.dart create mode 100644 lib/features/language/data/model/language_model.dart create mode 100644 lib/features/language/data/repository_impl/language_repository_impl.dart create mode 100644 lib/features/language/domain/entity/language_entity.dart create mode 100644 lib/features/language/domain/repository/language_repository.dart create mode 100644 lib/features/language/domain/usecases/get_language_usecase.dart create mode 100644 lib/features/language/presentation/bloc/language_bloc.dart create mode 100644 lib/features/language/presentation/bloc/language_event.dart create mode 100644 lib/features/language/presentation/bloc/language_state.dart create mode 100644 lib/features/language/presentation/ui/language_page.dart diff --git a/lib/core/params/language_params.dart b/lib/core/params/language_params.dart new file mode 100644 index 0000000..d44664b --- /dev/null +++ b/lib/core/params/language_params.dart @@ -0,0 +1,13 @@ +class LanguageParams { + int? id; + + LanguageParams({this.id}); + + LanguageParams copyWith({ + int? id, + }) { + return LanguageParams( + id: id ?? this.id, + ); + } +} diff --git a/lib/core/routers/my_routes.dart b/lib/core/routers/my_routes.dart index e7781c5..38b8191 100644 --- a/lib/core/routers/my_routes.dart +++ b/lib/core/routers/my_routes.dart @@ -5,6 +5,8 @@ import 'package:hadi_hoda_flutter/features/home/presentation/bloc/home_bloc.dart import 'package:hadi_hoda_flutter/features/home/presentation/ui/home_page.dart'; import 'package:hadi_hoda_flutter/features/intro/presentation/bloc/intro_bloc.dart'; import 'package:hadi_hoda_flutter/features/intro/presentation/ui/intro_page.dart'; +import 'package:hadi_hoda_flutter/features/language/presentation/bloc/language_bloc.dart'; +import 'package:hadi_hoda_flutter/features/language/presentation/ui/language_page.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/ui/level_page.dart'; @@ -19,13 +21,14 @@ class Routes { factory Routes() => _i; static const String introPage = '/intro_page'; + static const String languagePage = '/language_page'; static const String homePage = '/home_page'; static const String questionPage = '/question_page'; static const String levelPage = '/level_page'; } GoRouter get appPages => GoRouter( - initialLocation: Routes.introPage, + initialLocation: Routes.languagePage, navigatorKey: ContextProvider.navigatorKey, routes: [ GoRoute( @@ -36,6 +39,14 @@ GoRouter get appPages => GoRouter( child: const IntroPage(), ), ), + GoRoute( + name: Routes.languagePage, + path: Routes.languagePage, + builder: (context, state) => BlocProvider( + create: (context) => LanguageBloc(locator()), + child: const LanguagePage(), + ), + ), GoRoute( name: Routes.homePage, path: Routes.homePage, diff --git a/lib/features/language/data/datasource/language_datasource.dart b/lib/features/language/data/datasource/language_datasource.dart new file mode 100644 index 0000000..86a6e51 --- /dev/null +++ b/lib/features/language/data/datasource/language_datasource.dart @@ -0,0 +1,28 @@ +import 'package:hadi_hoda_flutter/core/constants/my_api.dart'; +import 'package:hadi_hoda_flutter/core/network/http_request.dart'; +import 'package:hadi_hoda_flutter/core/params/language_params.dart'; +import 'package:hadi_hoda_flutter/core/response/base_response.dart'; +import 'package:hadi_hoda_flutter/features/language/data/model/language_model.dart'; +import 'package:hadi_hoda_flutter/features/language/domain/entity/language_entity.dart'; + +abstract class ILanguageDatasource { + Future getData({required LanguageParams params}); +} + +class LanguageDatasourceImpl implements ILanguageDatasource { + final IHttpRequest httpRequest; + + const LanguageDatasourceImpl(this.httpRequest); + + @override + Future getData({required LanguageParams params}) async { + final response = await httpRequest.get( + path: MyApi.baseUrl, + ); + + return BaseResponse.getData( + response?['data'], + (json) => LanguageModel.fromJson(json), + ); + } +} diff --git a/lib/features/language/data/model/language_model.dart b/lib/features/language/data/model/language_model.dart new file mode 100644 index 0000000..17b73e0 --- /dev/null +++ b/lib/features/language/data/model/language_model.dart @@ -0,0 +1,13 @@ +import 'package:hadi_hoda_flutter/features/language/domain/entity/language_entity.dart'; + +class LanguageModel extends LanguageEntity { + const LanguageModel({ + super.id, + }); + + factory LanguageModel.fromJson(Map json) { + return LanguageModel( + id: json['id'], + ); + } +} diff --git a/lib/features/language/data/repository_impl/language_repository_impl.dart b/lib/features/language/data/repository_impl/language_repository_impl.dart new file mode 100644 index 0000000..64165a1 --- /dev/null +++ b/lib/features/language/data/repository_impl/language_repository_impl.dart @@ -0,0 +1,29 @@ +import 'package:hadi_hoda_flutter/core/params/language_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/language/data/datasource/language_datasource.dart'; +import 'package:hadi_hoda_flutter/features/language/domain/entity/language_entity.dart'; +import 'package:hadi_hoda_flutter/features/language/domain/repository/language_repository.dart'; + +class LanguageRepositoryImpl implements ILanguageRepository { + final ILanguageDatasource datasource; + + const LanguageRepositoryImpl(this.datasource); + + @override + Future> getData({required LanguageParams params}) async { + try { + final LanguageEntity 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/language/domain/entity/language_entity.dart b/lib/features/language/domain/entity/language_entity.dart new file mode 100644 index 0000000..12fdd5a --- /dev/null +++ b/lib/features/language/domain/entity/language_entity.dart @@ -0,0 +1,14 @@ +import 'package:equatable/equatable.dart'; + +class LanguageEntity extends Equatable { + final int? id; + + const LanguageEntity({ + this.id, + }); + + @override + List get props => [ + id, + ]; +} diff --git a/lib/features/language/domain/repository/language_repository.dart b/lib/features/language/domain/repository/language_repository.dart new file mode 100644 index 0000000..286e8cd --- /dev/null +++ b/lib/features/language/domain/repository/language_repository.dart @@ -0,0 +1,8 @@ +import 'package:hadi_hoda_flutter/core/error_handler/my_exception.dart'; +import 'package:hadi_hoda_flutter/core/params/language_params.dart'; +import 'package:hadi_hoda_flutter/core/utils/data_state.dart'; +import 'package:hadi_hoda_flutter/features/language/domain/entity/language_entity.dart'; + +abstract class ILanguageRepository { + Future> getData({required LanguageParams params}); +} diff --git a/lib/features/language/domain/usecases/get_language_usecase.dart b/lib/features/language/domain/usecases/get_language_usecase.dart new file mode 100644 index 0000000..ca3141e --- /dev/null +++ b/lib/features/language/domain/usecases/get_language_usecase.dart @@ -0,0 +1,17 @@ +import 'package:hadi_hoda_flutter/core/error_handler/my_exception.dart'; +import 'package:hadi_hoda_flutter/core/params/language_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/language/domain/entity/language_entity.dart'; +import 'package:hadi_hoda_flutter/features/language/domain/repository/language_repository.dart'; + +class GetLanguageUseCase implements UseCase { + final ILanguageRepository repository; + + const GetLanguageUseCase(this.repository); + + @override + Future> call(LanguageParams params) { + return repository.getData(params: params); + } +} diff --git a/lib/features/language/presentation/bloc/language_bloc.dart b/lib/features/language/presentation/bloc/language_bloc.dart new file mode 100644 index 0000000..4810ce8 --- /dev/null +++ b/lib/features/language/presentation/bloc/language_bloc.dart @@ -0,0 +1,41 @@ +import 'dart:async'; +import 'package:bloc/bloc.dart'; +import 'package:hadi_hoda_flutter/core/status/base_status.dart'; +import 'package:hadi_hoda_flutter/features/language/domain/entity/language_entity.dart'; +import 'package:hadi_hoda_flutter/features/language/domain/usecases/get_language_usecase.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'; + +class LanguageBloc extends Bloc { + /// ------------constructor------------ + LanguageBloc( + this._getLanguageUseCase, + ) : super(const LanguageState()) { + on(_getLanguageEvent); + } + + /// ------------UseCases------------ + final GetLanguageUseCase _getLanguageUseCase; + + /// ------------Variables------------ + + /// ------------Controllers------------ + + /// ------------Functions------------ + + /// ------------Api Calls------------ + FutureOr _getLanguageEvent(event, emit) async { + await _getLanguageUseCase(event.languageParams).then( + (value) { + value.fold( + (data) { + emit(state.copyWith(getLanguageStatus: BaseComplete(data))); + }, + (error) { + emit(state.copyWith(getLanguageStatus: BaseError(error.errorMessage))); + }, + ); + }, + ); + } +} diff --git a/lib/features/language/presentation/bloc/language_event.dart b/lib/features/language/presentation/bloc/language_event.dart new file mode 100644 index 0000000..418d6c0 --- /dev/null +++ b/lib/features/language/presentation/bloc/language_event.dart @@ -0,0 +1,5 @@ +sealed class LanguageEvent { + const LanguageEvent(); +} + +class GetLanguageEvent extends LanguageEvent {} diff --git a/lib/features/language/presentation/bloc/language_state.dart b/lib/features/language/presentation/bloc/language_state.dart new file mode 100644 index 0000000..033d817 --- /dev/null +++ b/lib/features/language/presentation/bloc/language_state.dart @@ -0,0 +1,15 @@ +import 'package:hadi_hoda_flutter/core/status/base_status.dart'; + +class LanguageState { + final BaseStatus getLanguageStatus; + + const LanguageState({this.getLanguageStatus = const BaseInit()}); + + LanguageState copyWith({ + BaseStatus? getLanguageStatus, + }) { + return LanguageState( + getLanguageStatus: getLanguageStatus ?? this.getLanguageStatus, + ); + } +} diff --git a/lib/features/language/presentation/ui/language_page.dart b/lib/features/language/presentation/ui/language_page.dart new file mode 100644 index 0000000..1d4abd1 --- /dev/null +++ b/lib/features/language/presentation/ui/language_page.dart @@ -0,0 +1,10 @@ +import 'package:flutter/material.dart'; + +class LanguagePage extends StatelessWidget { + const LanguagePage({super.key}); + + @override + Widget build(BuildContext context) { + return const Scaffold(); + } +} diff --git a/lib/init_bindings.dart b/lib/init_bindings.dart index c8c7a8c..8186a38 100644 --- a/lib/init_bindings.dart +++ b/lib/init_bindings.dart @@ -12,6 +12,10 @@ import 'package:hadi_hoda_flutter/features/intro/data/repository_impl/intro_repo import 'package:hadi_hoda_flutter/features/intro/domain/repository/intro_repository.dart'; import 'package:hadi_hoda_flutter/features/intro/domain/usecases/get_files_usecase.dart'; import 'package:hadi_hoda_flutter/features/intro/domain/usecases/loading_stream_usecase.dart'; +import 'package:hadi_hoda_flutter/features/language/data/datasource/language_datasource.dart'; +import 'package:hadi_hoda_flutter/features/language/data/repository_impl/language_repository_impl.dart'; +import 'package:hadi_hoda_flutter/features/language/domain/repository/language_repository.dart'; +import 'package:hadi_hoda_flutter/features/language/domain/usecases/get_language_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'; @@ -49,6 +53,11 @@ void initBindings() { locator.registerLazySingleton(() => GetFilesUseCase(locator())); locator.registerLazySingleton(() => LoadingStreamUseCase(locator())); + /// Language Feature + locator.registerLazySingleton(() => LanguageDatasourceImpl(locator())); + locator.registerLazySingleton(() => LanguageRepositoryImpl(locator())); + locator.registerLazySingleton(() => GetLanguageUseCase(locator())); + /// Home Feature locator.registerLazySingleton(() => HomeDatasourceImpl(locator())); locator.registerLazySingleton(() => HomeRepositoryImpl(locator())); -- 2.30.2 From 6c444d8e6b6e3c5aae88c24d3fd0eac09fadb290 Mon Sep 17 00:00:00 2001 From: AmirrezaChegini Date: Sat, 4 Oct 2025 13:29:09 +0330 Subject: [PATCH 2/3] add: get data based on language --- assets/images/button.svg | 44 ++++++ assets/images/button_2.svg | 51 ++++++ assets/images/lang.svg | 3 + assets/images/start.svg | 77 --------- lib/common_ui/resources/my_assets.dart | 4 +- lib/common_ui/resources/my_text_style.dart | 5 + lib/core/constants/my_constants.dart | 1 + lib/core/middleware/auth_middleware.dart | 20 --- lib/core/middleware/language_middleware.dart | 21 +++ lib/core/params/language_params.dart | 12 +- lib/core/routers/my_routes.dart | 4 +- lib/core/widgets/button/enum/button_type.dart | 18 +++ lib/core/widgets/button/my_button.dart | 50 ++++++ .../home/presentation/ui/home_page.dart | 2 +- .../intro/presentation/bloc/intro_bloc.dart | 2 +- .../data/datasource/language_datasource.dart | 38 +++-- .../language/data/model/language_model.dart | 13 -- .../language_repository_impl.dart | 8 +- .../domain/entity/language_entity.dart | 11 +- .../repository/language_repository.dart | 4 +- ..._usecase.dart => save_levels_usecase.dart} | 10 +- .../presentation/bloc/language_bloc.dart | 53 +++++-- .../presentation/bloc/language_event.dart | 13 +- .../presentation/bloc/language_state.dart | 15 +- .../presentation/ui/language_page.dart | 149 +++++++++++++++++- .../data/datasource/level_datasource.dart | 24 --- .../level/domain/entity/level_entity.dart | 2 +- .../level/domain/entity/level_entity.g.dart | 2 +- .../domain/entity/total_data_entity.dart | 17 ++ .../question/domain/entity/answer_entity.dart | 2 +- .../domain/entity/answer_entity.g.dart | 2 +- .../question/domain/entity/file_entity.dart | 2 +- .../question/domain/entity/file_entity.g.dart | 2 +- .../domain/entity/question_entity.dart | 2 +- .../domain/entity/question_entity.g.dart | 2 +- lib/init_bindings.dart | 10 +- lib/l10n/app_en.arb | 4 +- lib/l10n/app_localizations.dart | 12 ++ lib/l10n/app_localizations_en.dart | 6 + 39 files changed, 514 insertions(+), 203 deletions(-) create mode 100644 assets/images/button.svg create mode 100644 assets/images/button_2.svg create mode 100644 assets/images/lang.svg delete mode 100644 assets/images/start.svg delete mode 100644 lib/core/middleware/auth_middleware.dart create mode 100644 lib/core/middleware/language_middleware.dart create mode 100644 lib/core/widgets/button/enum/button_type.dart create mode 100644 lib/core/widgets/button/my_button.dart delete mode 100644 lib/features/language/data/model/language_model.dart rename lib/features/language/domain/usecases/{get_language_usecase.dart => save_levels_usecase.dart} (55%) create mode 100644 lib/features/level/domain/entity/total_data_entity.dart diff --git a/assets/images/button.svg b/assets/images/button.svg new file mode 100644 index 0000000..bc05b38 --- /dev/null +++ b/assets/images/button.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/button_2.svg b/assets/images/button_2.svg new file mode 100644 index 0000000..c27135a --- /dev/null +++ b/assets/images/button_2.svg @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/lang.svg b/assets/images/lang.svg new file mode 100644 index 0000000..c2452a0 --- /dev/null +++ b/assets/images/lang.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/start.svg b/assets/images/start.svg deleted file mode 100644 index 8151c85..0000000 --- a/assets/images/start.svg +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/lib/common_ui/resources/my_assets.dart b/lib/common_ui/resources/my_assets.dart index 041843e..063d962 100644 --- a/lib/common_ui/resources/my_assets.dart +++ b/lib/common_ui/resources/my_assets.dart @@ -8,7 +8,8 @@ class MyAssets { 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 start = 'assets/images/start.svg'; + static const String button = 'assets/images/button.svg'; + static const String button2 = 'assets/images/button_2.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'; @@ -36,4 +37,5 @@ class MyAssets { 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'; } \ No newline at end of file diff --git a/lib/common_ui/resources/my_text_style.dart b/lib/common_ui/resources/my_text_style.dart index de47e8f..1d93190 100644 --- a/lib/common_ui/resources/my_text_style.dart +++ b/lib/common_ui/resources/my_text_style.dart @@ -18,6 +18,11 @@ class DinoKids { fontSize: 26, fontWeight: FontWeight.w400, ); + static const TextStyle regular45 = TextStyle( + fontFamily: fontFamily, + fontSize: 45, + fontWeight: FontWeight.w400, + ); } class Marhey { diff --git a/lib/core/constants/my_constants.dart b/lib/core/constants/my_constants.dart index 7772e42..e96b59e 100644 --- a/lib/core/constants/my_constants.dart +++ b/lib/core/constants/my_constants.dart @@ -8,4 +8,5 @@ class MyConstants { static const String levelBox = 'LEVEL_BOX'; static const String downloadCompleted = 'DOWNLOAD_COMPLETED'; static const String extractCompleted = 'EXTRACT_COMPLETED'; + static const String selectLanguage = 'SELECT_LANGUAGE'; } \ No newline at end of file diff --git a/lib/core/middleware/auth_middleware.dart b/lib/core/middleware/auth_middleware.dart deleted file mode 100644 index a6901af..0000000 --- a/lib/core/middleware/auth_middleware.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/material.dart'; -import 'package:hadi_hoda_flutter/core/auth_storage/auth_storage.dart'; -import 'package:hadi_hoda_flutter/core/routers/my_routes.dart'; -import 'package:go_router/go_router.dart'; - -class AuthMiddleware { - static const AuthMiddleware _i = AuthMiddleware._internal(); - const AuthMiddleware._internal(); - factory AuthMiddleware() => _i; - - static FutureOr redirect(BuildContext context, GoRouterState state) async { - if (AuthStorage.isLogin()) { - return Routes.homePage; - } else { - return null; - } - } -} diff --git a/lib/core/middleware/language_middleware.dart b/lib/core/middleware/language_middleware.dart new file mode 100644 index 0000000..3d092bd --- /dev/null +++ b/lib/core/middleware/language_middleware.dart @@ -0,0 +1,21 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:hadi_hoda_flutter/core/constants/my_constants.dart'; +import 'package:hadi_hoda_flutter/core/routers/my_routes.dart'; +import 'package:go_router/go_router.dart'; +import 'package:hadi_hoda_flutter/core/utils/local_storage.dart'; + +class LanguageMiddleware { + static const LanguageMiddleware _i = LanguageMiddleware._internal(); + const LanguageMiddleware._internal(); + factory LanguageMiddleware() => _i; + + static FutureOr redirect(BuildContext context, GoRouterState state) async { + if (LocalStorage.readData(key: MyConstants.selectLanguage).isNotEmpty) { + return Routes.homePage; + } else { + return null; + } + } +} diff --git a/lib/core/params/language_params.dart b/lib/core/params/language_params.dart index d44664b..c5866ec 100644 --- a/lib/core/params/language_params.dart +++ b/lib/core/params/language_params.dart @@ -1,13 +1,17 @@ class LanguageParams { - int? id; + String? code; - LanguageParams({this.id}); + LanguageParams({this.code}); LanguageParams copyWith({ - int? id, + String? code, }) { return LanguageParams( - id: id ?? this.id, + code: code ?? this.code, ); } + + Map get toHeader => { + if (code != null) 'HTTP_X_USER_LANGUAGE': code, + }; } diff --git a/lib/core/routers/my_routes.dart b/lib/core/routers/my_routes.dart index 38b8191..5066c81 100644 --- a/lib/core/routers/my_routes.dart +++ b/lib/core/routers/my_routes.dart @@ -1,5 +1,6 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; +import 'package:hadi_hoda_flutter/core/middleware/language_middleware.dart'; import 'package:hadi_hoda_flutter/core/utils/context_provider.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'; @@ -28,7 +29,7 @@ class Routes { } GoRouter get appPages => GoRouter( - initialLocation: Routes.languagePage, + initialLocation: Routes.introPage, navigatorKey: ContextProvider.navigatorKey, routes: [ GoRoute( @@ -42,6 +43,7 @@ GoRouter get appPages => GoRouter( GoRoute( name: Routes.languagePage, path: Routes.languagePage, + redirect: LanguageMiddleware.redirect, builder: (context, state) => BlocProvider( create: (context) => LanguageBloc(locator()), child: const LanguagePage(), diff --git a/lib/core/widgets/button/enum/button_type.dart b/lib/core/widgets/button/enum/button_type.dart new file mode 100644 index 0000000..c347d64 --- /dev/null +++ b/lib/core/widgets/button/enum/button_type.dart @@ -0,0 +1,18 @@ +import 'dart:ui'; + +import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart'; + +enum ButtonType { + type1, + type2; + + static Map get image => { + type1: MyAssets.button, + type2: MyAssets.button2, + }; + + static Map get textColor => { + type1: Color(0XFF1D6EFF), + type2: Color(0XFFD93D16), + }; +} \ No newline at end of file diff --git a/lib/core/widgets/button/my_button.dart b/lib/core/widgets/button/my_button.dart new file mode 100644 index 0000000..188cb3a --- /dev/null +++ b/lib/core/widgets/button/my_button.dart @@ -0,0 +1,50 @@ +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/common_ui/theme/my_theme.dart'; +import 'package:hadi_hoda_flutter/core/utils/my_image.dart'; +import 'package:hadi_hoda_flutter/core/widgets/button/enum/button_type.dart'; + +class MyButton extends StatelessWidget { + const MyButton({ + super.key, + this.onTap, + this.type = ButtonType.type1, + this.title, + }); + + final VoidCallback? onTap; + final ButtonType? type; + final String? title; + + @override + Widget build(BuildContext context) { + return SizedBox( + height: 84, + width: 194, + child: InkWell( + onTap: onTap, + highlightColor: context.noColor, + splashColor: context.noColor, + child: Stack( + alignment: Alignment.center, + children: [ + MyImage( + image: ButtonType.image[type] ?? MyAssets.button, + ), + PositionedDirectional( + top: MySpaces.s2, + child: Text( + title ?? '', + style: DinoKids.regular45.copyWith( + color: ButtonType.textColor[type], + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/features/home/presentation/ui/home_page.dart b/lib/features/home/presentation/ui/home_page.dart index b6665fd..82c5c85 100644 --- a/lib/features/home/presentation/ui/home_page.dart +++ b/lib/features/home/presentation/ui/home_page.dart @@ -76,7 +76,7 @@ class HomePage extends StatelessWidget { ), InkWell( child: MyImage( - image: MyAssets.start, + image: MyAssets.button, size: checkSize(context: context, mobile: 90, tablet: 160), ), onTap: () => diff --git a/lib/features/intro/presentation/bloc/intro_bloc.dart b/lib/features/intro/presentation/bloc/intro_bloc.dart index 9ec1665..26fbddd 100644 --- a/lib/features/intro/presentation/bloc/intro_bloc.dart +++ b/lib/features/intro/presentation/bloc/intro_bloc.dart @@ -40,7 +40,7 @@ class IntroBloc extends Bloc { (data) async { await Future.delayed( Duration(milliseconds: 300), () { - ContextProvider.context!.goNamed(Routes.homePage); + ContextProvider.context!.goNamed(Routes.languagePage); }, ); }, diff --git a/lib/features/language/data/datasource/language_datasource.dart b/lib/features/language/data/datasource/language_datasource.dart index 86a6e51..6c37a9d 100644 --- a/lib/features/language/data/datasource/language_datasource.dart +++ b/lib/features/language/data/datasource/language_datasource.dart @@ -1,12 +1,16 @@ 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/network/http_request.dart'; import 'package:hadi_hoda_flutter/core/params/language_params.dart'; import 'package:hadi_hoda_flutter/core/response/base_response.dart'; -import 'package:hadi_hoda_flutter/features/language/data/model/language_model.dart'; -import 'package:hadi_hoda_flutter/features/language/domain/entity/language_entity.dart'; +import 'package:hadi_hoda_flutter/core/utils/local_storage.dart'; +import 'package:hadi_hoda_flutter/features/level/data/model/level_model.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 ILanguageDatasource { - Future getData({required LanguageParams params}); + Future saveLevels({required LanguageParams params}); } class LanguageDatasourceImpl implements ILanguageDatasource { @@ -15,14 +19,28 @@ class LanguageDatasourceImpl implements ILanguageDatasource { const LanguageDatasourceImpl(this.httpRequest); @override - Future getData({required LanguageParams params}) async { - final response = await httpRequest.get( - path: MyApi.baseUrl, + Future saveLevels({required LanguageParams params}) async { + await LocalStorage.saveData( + key: MyConstants.selectLanguage, + value: params.code ?? 'fa', ); - - return BaseResponse.getData( - response?['data'], - (json) => LanguageModel.fromJson(json), + final Box data = Hive.box(MyConstants.levelBox); + final TotalDataEntity findData = data.values.singleWhere( + (e) => e.code == params.code, + orElse: () => TotalDataEntity(), ); + + if (findData.code != params.code) { + final response = await httpRequest.get( + path: MyApi.levels, + header: params.toHeader, + ); + final List levels = BaseResponse.getDataList( + response?['result'], + (json) => LevelModel.fromJson(json), + ); + + await data.add(TotalDataEntity(code: params.code, levels: levels)); + } } } diff --git a/lib/features/language/data/model/language_model.dart b/lib/features/language/data/model/language_model.dart deleted file mode 100644 index 17b73e0..0000000 --- a/lib/features/language/data/model/language_model.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:hadi_hoda_flutter/features/language/domain/entity/language_entity.dart'; - -class LanguageModel extends LanguageEntity { - const LanguageModel({ - super.id, - }); - - factory LanguageModel.fromJson(Map json) { - return LanguageModel( - id: json['id'], - ); - } -} diff --git a/lib/features/language/data/repository_impl/language_repository_impl.dart b/lib/features/language/data/repository_impl/language_repository_impl.dart index 64165a1..7441fac 100644 --- a/lib/features/language/data/repository_impl/language_repository_impl.dart +++ b/lib/features/language/data/repository_impl/language_repository_impl.dart @@ -1,9 +1,9 @@ import 'package:hadi_hoda_flutter/core/params/language_params.dart'; 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/language/data/datasource/language_datasource.dart'; -import 'package:hadi_hoda_flutter/features/language/domain/entity/language_entity.dart'; import 'package:hadi_hoda_flutter/features/language/domain/repository/language_repository.dart'; class LanguageRepositoryImpl implements ILanguageRepository { @@ -12,10 +12,10 @@ class LanguageRepositoryImpl implements ILanguageRepository { const LanguageRepositoryImpl(this.datasource); @override - Future> getData({required LanguageParams params}) async { + Future> saveLevels({required LanguageParams params}) async { try { - final LanguageEntity response = await datasource.getData(params: params); - return DataState.success(response); + await datasource.saveLevels(params: params); + return DataState.success(NoParams()); } on MyException catch (e) { return DataState.error(e); } catch (e) { diff --git a/lib/features/language/domain/entity/language_entity.dart b/lib/features/language/domain/entity/language_entity.dart index 12fdd5a..2e76d7a 100644 --- a/lib/features/language/domain/entity/language_entity.dart +++ b/lib/features/language/domain/entity/language_entity.dart @@ -1,14 +1,17 @@ import 'package:equatable/equatable.dart'; class LanguageEntity extends Equatable { - final int? id; + final String? title; + final String? code; const LanguageEntity({ - this.id, + this.title, + this.code, }); @override List get props => [ - id, - ]; + title, + code, + ]; } diff --git a/lib/features/language/domain/repository/language_repository.dart b/lib/features/language/domain/repository/language_repository.dart index 286e8cd..734c561 100644 --- a/lib/features/language/domain/repository/language_repository.dart +++ b/lib/features/language/domain/repository/language_repository.dart @@ -1,8 +1,8 @@ import 'package:hadi_hoda_flutter/core/error_handler/my_exception.dart'; import 'package:hadi_hoda_flutter/core/params/language_params.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/language/domain/entity/language_entity.dart'; abstract class ILanguageRepository { - Future> getData({required LanguageParams params}); + Future> saveLevels({required LanguageParams params}); } diff --git a/lib/features/language/domain/usecases/get_language_usecase.dart b/lib/features/language/domain/usecases/save_levels_usecase.dart similarity index 55% rename from lib/features/language/domain/usecases/get_language_usecase.dart rename to lib/features/language/domain/usecases/save_levels_usecase.dart index ca3141e..61c6546 100644 --- a/lib/features/language/domain/usecases/get_language_usecase.dart +++ b/lib/features/language/domain/usecases/save_levels_usecase.dart @@ -1,17 +1,17 @@ import 'package:hadi_hoda_flutter/core/error_handler/my_exception.dart'; import 'package:hadi_hoda_flutter/core/params/language_params.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/language/domain/entity/language_entity.dart'; import 'package:hadi_hoda_flutter/features/language/domain/repository/language_repository.dart'; -class GetLanguageUseCase implements UseCase { +class SaveLevelsUseCase implements UseCase { final ILanguageRepository repository; - const GetLanguageUseCase(this.repository); + const SaveLevelsUseCase(this.repository); @override - Future> call(LanguageParams params) { - return repository.getData(params: params); + Future> call(LanguageParams params) { + return repository.saveLevels(params: params); } } diff --git a/lib/features/language/presentation/bloc/language_bloc.dart b/lib/features/language/presentation/bloc/language_bloc.dart index 4810ce8..c339a88 100644 --- a/lib/features/language/presentation/bloc/language_bloc.dart +++ b/lib/features/language/presentation/bloc/language_bloc.dart @@ -1,41 +1,60 @@ import 'dart:async'; import 'package:bloc/bloc.dart'; +import 'package:go_router/go_router.dart'; +import 'package:hadi_hoda_flutter/core/params/language_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/features/language/domain/entity/language_entity.dart'; -import 'package:hadi_hoda_flutter/features/language/domain/usecases/get_language_usecase.dart'; +import 'package:hadi_hoda_flutter/features/language/domain/usecases/save_levels_usecase.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'; class LanguageBloc extends Bloc { /// ------------constructor------------ LanguageBloc( - this._getLanguageUseCase, + this._saveLevelsUseCase, ) : super(const LanguageState()) { - on(_getLanguageEvent); + on(_changeLanguageEvent); + on(_saveLevelsEvent); } /// ------------UseCases------------ - final GetLanguageUseCase _getLanguageUseCase; + final SaveLevelsUseCase _saveLevelsUseCase; /// ------------Variables------------ + final List languages = [ + LanguageEntity(title: 'Persian (فارسی)', code: 'fa'), + LanguageEntity(title: 'English (English)', code: 'en'), + LanguageEntity(title: 'Arabic (عربی)', code: 'ar'), + ]; /// ------------Controllers------------ /// ------------Functions------------ + FutureOr _changeLanguageEvent( + ChangeLanguageEvent event, + Emitter emit, + ) { + emit(state.copyWith(selectedLang: event.lang)); + } /// ------------Api Calls------------ - FutureOr _getLanguageEvent(event, emit) async { - await _getLanguageUseCase(event.languageParams).then( - (value) { - value.fold( - (data) { - emit(state.copyWith(getLanguageStatus: BaseComplete(data))); - }, - (error) { - emit(state.copyWith(getLanguageStatus: BaseError(error.errorMessage))); - }, - ); - }, - ); + FutureOr _saveLevelsEvent( + SaveLevelsEvent event, + Emitter emit, + ) async { + emit(state.copyWith(saveLevelsStatus: const BaseLoading())); + await _saveLevelsUseCase(LanguageParams(code: state.selectedLang.code)).then( + (value) => value.fold( + (data) { + emit(state.copyWith(saveLevelsStatus: const BaseInit())); + ContextProvider.context!.goNamed(Routes.homePage); + }, + (error) { + emit(state.copyWith(saveLevelsStatus: const BaseInit())); + }, + ), + ); } } diff --git a/lib/features/language/presentation/bloc/language_event.dart b/lib/features/language/presentation/bloc/language_event.dart index 418d6c0..2531db4 100644 --- a/lib/features/language/presentation/bloc/language_event.dart +++ b/lib/features/language/presentation/bloc/language_event.dart @@ -1,5 +1,16 @@ +import 'package:hadi_hoda_flutter/features/language/domain/entity/language_entity.dart'; + sealed class LanguageEvent { const LanguageEvent(); } -class GetLanguageEvent extends LanguageEvent {} +class ChangeLanguageEvent extends LanguageEvent { + final LanguageEntity lang; + + const ChangeLanguageEvent(this.lang); +} + +class SaveLevelsEvent extends LanguageEvent { + const SaveLevelsEvent(); +} + diff --git a/lib/features/language/presentation/bloc/language_state.dart b/lib/features/language/presentation/bloc/language_state.dart index 033d817..44d40bb 100644 --- a/lib/features/language/presentation/bloc/language_state.dart +++ b/lib/features/language/presentation/bloc/language_state.dart @@ -1,15 +1,22 @@ import 'package:hadi_hoda_flutter/core/status/base_status.dart'; +import 'package:hadi_hoda_flutter/features/language/domain/entity/language_entity.dart'; class LanguageState { - final BaseStatus getLanguageStatus; + final BaseStatus saveLevelsStatus; + final LanguageEntity selectedLang; - const LanguageState({this.getLanguageStatus = const BaseInit()}); + const LanguageState({ + this.saveLevelsStatus = const BaseInit(), + this.selectedLang = const LanguageEntity(code: 'fa'), + }); LanguageState copyWith({ - BaseStatus? getLanguageStatus, + BaseStatus? saveLevelsStatus, + LanguageEntity? selectedLang, }) { return LanguageState( - getLanguageStatus: getLanguageStatus ?? this.getLanguageStatus, + saveLevelsStatus: saveLevelsStatus ?? this.saveLevelsStatus, + selectedLang: selectedLang ?? this.selectedLang, ); } } diff --git a/lib/features/language/presentation/ui/language_page.dart b/lib/features/language/presentation/ui/language_page.dart index 1d4abd1..4c81130 100644 --- a/lib/features/language/presentation/ui/language_page.dart +++ b/lib/features/language/presentation/ui/language_page.dart @@ -1,10 +1,157 @@ +import 'package:flutter/cupertino.dart'; 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/common_ui/resources/my_text_style.dart'; +import 'package:hadi_hoda_flutter/common_ui/theme/my_theme.dart'; +import 'package:hadi_hoda_flutter/core/status/base_status.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/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'; class LanguagePage extends StatelessWidget { const LanguagePage({super.key}); @override Widget build(BuildContext context) { - return const Scaffold(); + return Scaffold( + body: Container( + height: context.heightScreen, + width: context.widthScreen, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [Color(0XFF00154C), Color(0XFF150532)], + ), + image: DecorationImage( + image: AssetImage(MyAssets.pattern), + scale: 3, + repeat: ImageRepeat.repeat, + colorFilter: ColorFilter.mode( + Colors.white.withValues(alpha: 0.2), + BlendMode.srcIn, + ), + ), + ), + child: Padding( + padding: EdgeInsets.only( + left: 60, + right: 60, + bottom: MediaQuery.viewPaddingOf(context).bottom + MySpaces.s16, + top: MediaQuery.viewPaddingOf(context).bottom + 50, + ), + child: Column( + children: [_title(context), _list(context), _btn(context)], + ), + ), + ), + ); + } + + Widget _title(BuildContext context) { + return Row( + spacing: MySpaces.s10, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + MyImage(image: MyAssets.lang, size: 28), + Text( + context.translate.select_language, + style: Marhey.semiBold22.copyWith(color: Color(0XFF847AC4)), + ), + ], + ); + } + + Expanded _list(BuildContext context) { + return Expanded( + child: Material( + color: context.noColor, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: List.generate( + context.read().languages.length, + (index) => BlocBuilder( + buildWhen: (previous, current) => + previous.selectedLang.code != current.selectedLang.code, + builder: (context, state) { + final LanguageBloc languageBloc = context.read(); + return ListTile( + selected: state.selectedLang.code == + languageBloc.languages[index].code, + onTap: () { + languageBloc.add( + ChangeLanguageEvent(languageBloc.languages[index])); + }, + title: Text(context.read().languages[index].title ?? ''), + titleTextStyle: Marhey.medium16.copyWith( + color: context.primaryColor, + ), + contentPadding: EdgeInsets.symmetric( + vertical: MySpaces.s12, + horizontal: 30, + ), + minVerticalPadding: 0, + minTileHeight: 0, + minLeadingWidth: 0, + horizontalTitleGap: MySpaces.s12, + trailing: BlocBuilder( + builder: (context, state) { + if (state.saveLevelsStatus is BaseLoading && (state + .selectedLang.code == languageBloc.languages[index].code)) { + return CupertinoActivityIndicator( + color: context.primaryColor, + ); + } else { + return SizedBox.shrink(); + } + }, + ), + leading: state.selectedLang.code == + languageBloc.languages[index].code ? Container( + height: 17, + width: 17, + padding: EdgeInsets.all(3), + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all( + width: 1, + color: Color(0XFF3CFF3C), + ), + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Color(0XFF48D336), + Color(0XFF2D7C23), + ], + ), + ), + child: MyImage(image: MyAssets.doneRounded), + ) : SizedBox(height: 17, width: 17), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(12)), + ), + selectedTileColor: context.primaryColor.withValues(alpha: 0.2), + selectedColor: context.primaryColor, + ); + } + ), + ), + ), + ), + ); + } + + Widget _btn(BuildContext context) { + return MyButton( + onTap: () => context.read().add(SaveLevelsEvent()), + title: context.translate.select, + ); } } diff --git a/lib/features/level/data/datasource/level_datasource.dart b/lib/features/level/data/datasource/level_datasource.dart index 77abd2b..1921cc1 100644 --- a/lib/features/level/data/datasource/level_datasource.dart +++ b/lib/features/level/data/datasource/level_datasource.dart @@ -1,10 +1,6 @@ -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/params/level_params.dart'; -import 'package:hadi_hoda_flutter/core/response/base_response.dart'; -import 'package:hadi_hoda_flutter/features/level/data/model/level_model.dart'; import 'package:hadi_hoda_flutter/features/level/domain/entity/level_entity.dart'; import 'package:hive/hive.dart'; @@ -12,26 +8,6 @@ abstract class ILevelDatasource { Future> getLevels({required LevelParams params}); } -/// Remote -class RemoteLevelDatasourceImpl implements ILevelDatasource { - final IHttpRequest httpRequest; - - const RemoteLevelDatasourceImpl(this.httpRequest); - - @override - Future> getLevels({required LevelParams params}) async { - final response = await httpRequest.get( - path: MyApi.baseUrl, - ); - - return BaseResponse.getDataList( - response?['data'], - (json) => LevelModel.fromJson(json), - ); - } -} - - /// Local class LocalLevelDatasourceImpl implements ILevelDatasource { diff --git a/lib/features/level/domain/entity/level_entity.dart b/lib/features/level/domain/entity/level_entity.dart index 196bd26..cee3840 100644 --- a/lib/features/level/domain/entity/level_entity.dart +++ b/lib/features/level/domain/entity/level_entity.dart @@ -3,7 +3,7 @@ import 'package:hive/hive.dart'; part 'level_entity.g.dart'; -@HiveType(typeId: 0) +@HiveType(typeId: 1) class LevelEntity extends HiveObject { @HiveField(0) int? id; diff --git a/lib/features/level/domain/entity/level_entity.g.dart b/lib/features/level/domain/entity/level_entity.g.dart index 7c5ddd0..22ae93a 100644 --- a/lib/features/level/domain/entity/level_entity.g.dart +++ b/lib/features/level/domain/entity/level_entity.g.dart @@ -8,7 +8,7 @@ part of 'level_entity.dart'; class LevelEntityAdapter extends TypeAdapter { @override - final int typeId = 0; + final int typeId = 1; @override LevelEntity read(BinaryReader reader) { diff --git a/lib/features/level/domain/entity/total_data_entity.dart b/lib/features/level/domain/entity/total_data_entity.dart new file mode 100644 index 0000000..1428455 --- /dev/null +++ b/lib/features/level/domain/entity/total_data_entity.dart @@ -0,0 +1,17 @@ +import 'package:hadi_hoda_flutter/features/level/domain/entity/level_entity.dart'; +import 'package:hive/hive.dart'; + +part 'total_data_entity.g.dart'; + +@HiveType(typeId: 0) +class TotalDataEntity extends HiveObject{ + @HiveField(0) + String? code; + @HiveField(1) + List? levels; + + TotalDataEntity({ + this.code, + this.levels, + }); +} \ No newline at end of file diff --git a/lib/features/question/domain/entity/answer_entity.dart b/lib/features/question/domain/entity/answer_entity.dart index e3204e0..d2fa120 100644 --- a/lib/features/question/domain/entity/answer_entity.dart +++ b/lib/features/question/domain/entity/answer_entity.dart @@ -3,7 +3,7 @@ import 'package:hive/hive.dart'; part 'answer_entity.g.dart'; -@HiveType(typeId: 2) +@HiveType(typeId: 3) class AnswerEntity extends HiveObject { @HiveField(0) int? id; diff --git a/lib/features/question/domain/entity/answer_entity.g.dart b/lib/features/question/domain/entity/answer_entity.g.dart index 34a06de..17f432c 100644 --- a/lib/features/question/domain/entity/answer_entity.g.dart +++ b/lib/features/question/domain/entity/answer_entity.g.dart @@ -8,7 +8,7 @@ part of 'answer_entity.dart'; class AnswerEntityAdapter extends TypeAdapter { @override - final int typeId = 2; + final int typeId = 3; @override AnswerEntity read(BinaryReader reader) { diff --git a/lib/features/question/domain/entity/file_entity.dart b/lib/features/question/domain/entity/file_entity.dart index 9446384..6faaf73 100644 --- a/lib/features/question/domain/entity/file_entity.dart +++ b/lib/features/question/domain/entity/file_entity.dart @@ -2,7 +2,7 @@ import 'package:hive/hive.dart'; part 'file_entity.g.dart'; -@HiveType(typeId: 3) +@HiveType(typeId: 4) class FileEntity extends HiveObject { @HiveField(0) String? filename; diff --git a/lib/features/question/domain/entity/file_entity.g.dart b/lib/features/question/domain/entity/file_entity.g.dart index 964bef5..ef3f994 100644 --- a/lib/features/question/domain/entity/file_entity.g.dart +++ b/lib/features/question/domain/entity/file_entity.g.dart @@ -8,7 +8,7 @@ part of 'file_entity.dart'; class FileEntityAdapter extends TypeAdapter { @override - final int typeId = 3; + final int typeId = 4; @override FileEntity read(BinaryReader reader) { diff --git a/lib/features/question/domain/entity/question_entity.dart b/lib/features/question/domain/entity/question_entity.dart index 4c05d26..3407e84 100644 --- a/lib/features/question/domain/entity/question_entity.dart +++ b/lib/features/question/domain/entity/question_entity.dart @@ -4,7 +4,7 @@ import 'package:hive/hive.dart'; part 'question_entity.g.dart'; -@HiveType(typeId: 1) +@HiveType(typeId: 2) class QuestionEntity extends HiveObject { @HiveField(0) int? id; diff --git a/lib/features/question/domain/entity/question_entity.g.dart b/lib/features/question/domain/entity/question_entity.g.dart index d90e05f..db9d48a 100644 --- a/lib/features/question/domain/entity/question_entity.g.dart +++ b/lib/features/question/domain/entity/question_entity.g.dart @@ -8,7 +8,7 @@ part of 'question_entity.dart'; class QuestionEntityAdapter extends TypeAdapter { @override - final int typeId = 1; + final int typeId = 2; @override QuestionEntity read(BinaryReader reader) { diff --git a/lib/init_bindings.dart b/lib/init_bindings.dart index 8186a38..bad6e5e 100644 --- a/lib/init_bindings.dart +++ b/lib/init_bindings.dart @@ -15,10 +15,11 @@ import 'package:hadi_hoda_flutter/features/intro/domain/usecases/loading_stream_ import 'package:hadi_hoda_flutter/features/language/data/datasource/language_datasource.dart'; import 'package:hadi_hoda_flutter/features/language/data/repository_impl/language_repository_impl.dart'; import 'package:hadi_hoda_flutter/features/language/domain/repository/language_repository.dart'; -import 'package:hadi_hoda_flutter/features/language/domain/usecases/get_language_usecase.dart'; +import 'package:hadi_hoda_flutter/features/language/domain/usecases/save_levels_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'; +import 'package:hadi_hoda_flutter/features/level/domain/entity/total_data_entity.dart'; import 'package:hadi_hoda_flutter/features/level/domain/repository/level_repository.dart'; import 'package:hadi_hoda_flutter/features/level/domain/usecases/get_levels_usecase.dart'; import 'package:hadi_hoda_flutter/features/question/data/datasource/question_datasource.dart'; @@ -56,7 +57,7 @@ void initBindings() { /// Language Feature locator.registerLazySingleton(() => LanguageDatasourceImpl(locator())); locator.registerLazySingleton(() => LanguageRepositoryImpl(locator())); - locator.registerLazySingleton(() => GetLanguageUseCase(locator())); + locator.registerLazySingleton(() => SaveLevelsUseCase(locator())); /// Home Feature locator.registerLazySingleton(() => HomeDatasourceImpl(locator())); @@ -81,7 +82,8 @@ Future initDataBase() async { ..registerAdapter(FileEntityAdapter()) ..registerAdapter(AnswerEntityAdapter()) ..registerAdapter(QuestionEntityAdapter()) - ..registerAdapter(LevelEntityAdapter()); + ..registerAdapter(LevelEntityAdapter()) + ..registerAdapter(TotalDataEntityAdapter()); - await Hive.openBox(MyConstants.levelBox); + await Hive.openBox(MyConstants.levelBox); } \ No newline at end of file diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index f21e3f9..fd36a8d 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -1,5 +1,7 @@ { "about_us": "About us", "about_us_desc" : "Rive combines an interactive design tool, a new stateful graphics format, a lightweight multi-platform runtime, and a blazing-fast vector renderer. \nThis end-to-end pipeline brings interfaces to life with motion. It gives designers and devs the tools to build.", - "tap_to_select": "Tap the correct option to select." + "tap_to_select": "Tap the correct option to select.", + "select_language": "Select language", + "select": "Select" } \ No newline at end of file diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 6e94635..8b63165 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -111,6 +111,18 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'Tap the correct option to select.'** String get tap_to_select; + + /// No description provided for @select_language. + /// + /// In en, this message translates to: + /// **'Select language'** + String get select_language; + + /// No description provided for @select. + /// + /// In en, this message translates to: + /// **'Select'** + String get select; } class _AppLocalizationsDelegate diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 6b8bd59..290f727 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -17,4 +17,10 @@ class AppLocalizationsEn extends AppLocalizations { @override String get tap_to_select => 'Tap the correct option to select.'; + + @override + String get select_language => 'Select language'; + + @override + String get select => 'Select'; } -- 2.30.2 From a257bb9dc28c5298ed19f65b888f9953ecd8d2e4 Mon Sep 17 00:00:00 2001 From: AmirrezaChegini Date: Sat, 4 Oct 2025 13:29:34 +0330 Subject: [PATCH 3/3] add: total data adapter --- .../domain/entity/total_data_entity.g.dart | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 lib/features/level/domain/entity/total_data_entity.g.dart diff --git a/lib/features/level/domain/entity/total_data_entity.g.dart b/lib/features/level/domain/entity/total_data_entity.g.dart new file mode 100644 index 0000000..947076d --- /dev/null +++ b/lib/features/level/domain/entity/total_data_entity.g.dart @@ -0,0 +1,44 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'total_data_entity.dart'; + +// ************************************************************************** +// TypeAdapterGenerator +// ************************************************************************** + +class TotalDataEntityAdapter extends TypeAdapter { + @override + final int typeId = 0; + + @override + TotalDataEntity read(BinaryReader reader) { + final numOfFields = reader.readByte(); + final fields = { + for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(), + }; + return TotalDataEntity( + code: fields[0] as String?, + levels: (fields[1] as List?)?.cast(), + ); + } + + @override + void write(BinaryWriter writer, TotalDataEntity obj) { + writer + ..writeByte(2) + ..writeByte(0) + ..write(obj.code) + ..writeByte(1) + ..write(obj.levels); + } + + @override + int get hashCode => typeId.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is TotalDataEntityAdapter && + runtimeType == other.runtimeType && + typeId == other.typeId; +} -- 2.30.2