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
new file mode 100644
index 0000000..c5866ec
--- /dev/null
+++ b/lib/core/params/language_params.dart
@@ -0,0 +1,17 @@
+class LanguageParams {
+ String? code;
+
+ LanguageParams({this.code});
+
+ LanguageParams copyWith({
+ String? code,
+ }) {
+ return LanguageParams(
+ 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 e7781c5..5066c81 100644
--- a/lib/core/routers/my_routes.dart
+++ b/lib/core/routers/my_routes.dart
@@ -1,10 +1,13 @@
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';
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,6 +22,7 @@ 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';
@@ -36,6 +40,15 @@ GoRouter get appPages => GoRouter(
child: const IntroPage(),
),
),
+ GoRoute(
+ name: Routes.languagePage,
+ path: Routes.languagePage,
+ redirect: LanguageMiddleware.redirect,
+ builder: (context, state) => BlocProvider(
+ create: (context) => LanguageBloc(locator()),
+ child: const LanguagePage(),
+ ),
+ ),
GoRoute(
name: Routes.homePage,
path: Routes.homePage,
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
new file mode 100644
index 0000000..6c37a9d
--- /dev/null
+++ b/lib/features/language/data/datasource/language_datasource.dart
@@ -0,0 +1,46 @@
+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/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 saveLevels({required LanguageParams params});
+}
+
+class LanguageDatasourceImpl implements ILanguageDatasource {
+ final IHttpRequest httpRequest;
+
+ const LanguageDatasourceImpl(this.httpRequest);
+
+ @override
+ Future saveLevels({required LanguageParams params}) async {
+ await LocalStorage.saveData(
+ key: MyConstants.selectLanguage,
+ value: params.code ?? 'fa',
+ );
+ 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/repository_impl/language_repository_impl.dart b/lib/features/language/data/repository_impl/language_repository_impl.dart
new file mode 100644
index 0000000..7441fac
--- /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/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/repository/language_repository.dart';
+
+class LanguageRepositoryImpl implements ILanguageRepository {
+ final ILanguageDatasource datasource;
+
+ const LanguageRepositoryImpl(this.datasource);
+
+ @override
+ Future> saveLevels({required LanguageParams params}) async {
+ try {
+ await datasource.saveLevels(params: params);
+ return DataState.success(NoParams());
+ } 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..2e76d7a
--- /dev/null
+++ b/lib/features/language/domain/entity/language_entity.dart
@@ -0,0 +1,17 @@
+import 'package:equatable/equatable.dart';
+
+class LanguageEntity extends Equatable {
+ final String? title;
+ final String? code;
+
+ const LanguageEntity({
+ this.title,
+ this.code,
+ });
+
+ @override
+ List