39 changed files with 514 additions and 203 deletions
-
44assets/images/button.svg
-
51assets/images/button_2.svg
-
3assets/images/lang.svg
-
77assets/images/start.svg
-
4lib/common_ui/resources/my_assets.dart
-
5lib/common_ui/resources/my_text_style.dart
-
1lib/core/constants/my_constants.dart
-
20lib/core/middleware/auth_middleware.dart
-
21lib/core/middleware/language_middleware.dart
-
12lib/core/params/language_params.dart
-
4lib/core/routers/my_routes.dart
-
18lib/core/widgets/button/enum/button_type.dart
-
50lib/core/widgets/button/my_button.dart
-
2lib/features/home/presentation/ui/home_page.dart
-
2lib/features/intro/presentation/bloc/intro_bloc.dart
-
38lib/features/language/data/datasource/language_datasource.dart
-
13lib/features/language/data/model/language_model.dart
-
8lib/features/language/data/repository_impl/language_repository_impl.dart
-
11lib/features/language/domain/entity/language_entity.dart
-
4lib/features/language/domain/repository/language_repository.dart
-
10lib/features/language/domain/usecases/save_levels_usecase.dart
-
53lib/features/language/presentation/bloc/language_bloc.dart
-
13lib/features/language/presentation/bloc/language_event.dart
-
15lib/features/language/presentation/bloc/language_state.dart
-
149lib/features/language/presentation/ui/language_page.dart
-
24lib/features/level/data/datasource/level_datasource.dart
-
2lib/features/level/domain/entity/level_entity.dart
-
2lib/features/level/domain/entity/level_entity.g.dart
-
17lib/features/level/domain/entity/total_data_entity.dart
-
2lib/features/question/domain/entity/answer_entity.dart
-
2lib/features/question/domain/entity/answer_entity.g.dart
-
2lib/features/question/domain/entity/file_entity.dart
-
2lib/features/question/domain/entity/file_entity.g.dart
-
2lib/features/question/domain/entity/question_entity.dart
-
2lib/features/question/domain/entity/question_entity.g.dart
-
10lib/init_bindings.dart
-
4lib/l10n/app_en.arb
-
12lib/l10n/app_localizations.dart
-
6lib/l10n/app_localizations_en.dart
@ -0,0 +1,44 @@ |
|||||
|
<svg width="198" height="93" viewBox="0 0 198 93" fill="none" xmlns="http://www.w3.org/2000/svg"> |
||||
|
<g filter="url(#filter0_d_66_104)"> |
||||
|
<path d="M188.461 75.3351C188.278 75.5102 188.081 75.673 187.872 75.8222C171.323 88.1843 27.7109 87.7476 7.66766 76.6452C6.79485 76.2265 6.06847 75.5921 5.5714 74.8144C-1.50808 61.3774 2.33508 20.7639 13.5887 11.9795C25.6882 2.57354 170.109 -1.69272 185.041 10.2998C196.055 19.0507 201.278 63.0402 188.461 75.3351Z" fill="url(#paint0_linear_66_104)"/> |
||||
|
</g> |
||||
|
<path d="M5.62633 72.1439C12.4668 85.161 174.357 86.2024 188.461 72.6813C201.332 60.3865 196.055 16.3801 185.096 7.61248C170.164 -4.34649 25.7431 -0.0970216 13.662 9.29211C2.38999 18.0598 -1.45315 58.6732 5.62633 72.1439Z" fill="url(#paint1_linear_66_104)"/> |
||||
|
<path d="M183.044 69.9851C182.872 70.1391 182.688 70.2824 182.492 70.4137C166.952 81.2903 32.1063 80.906 13.2866 71.1378C12.4671 70.7694 11.785 70.2112 11.3183 69.527C4.67096 57.7046 8.27953 21.9714 18.8462 14.2425C30.2071 5.96688 165.813 2.21327 179.833 12.7647C190.175 20.4641 195.078 59.1676 183.044 69.9851Z" fill="url(#paint2_linear_66_104)"/> |
||||
|
<path d="M11.3698 67.1773C17.7927 78.6302 169.801 79.5465 183.044 67.6502C195.13 56.8327 190.175 18.1144 179.884 10.4003C165.864 -0.121644 30.2586 3.61719 18.915 11.8781C8.33101 19.5922 4.72246 55.3254 11.3698 67.1773Z" fill="url(#paint3_linear_66_104)"/> |
||||
|
<path style="mix-blend-mode:screen" opacity="0.5" d="M35.3606 9.55896C35.3606 9.55896 129.168 -2.28615 178.184 10.2901C181.245 13.8661 183.203 17.563 184.011 21.2907C171.774 25.9233 155.491 28.399 138.38 28.2285C112.852 28.1796 88.6321 14.0536 67.1617 11.752C56.7526 10.4783 46.0686 9.74151 35.3606 9.55896Z" fill="url(#paint4_linear_66_104)"/> |
||||
|
<defs> |
||||
|
<filter id="filter0_d_66_104" x="0.37037" y="2.96387" width="197.232" height="89.8103" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"> |
||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/> |
||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/> |
||||
|
<feOffset dy="6.11111"/> |
||||
|
<feGaussianBlur stdDeviation="0.814815"/> |
||||
|
<feComposite in2="hardAlpha" operator="out"/> |
||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/> |
||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_66_104"/> |
||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_66_104" result="shape"/> |
||||
|
</filter> |
||||
|
<linearGradient id="paint0_linear_66_104" x1="99.0205" y1="85.0434" x2="99.0205" y2="2.95985" gradientUnits="userSpaceOnUse"> |
||||
|
<stop stop-color="#8B9AD1"/> |
||||
|
<stop offset="1" stop-color="#CEE0FF"/> |
||||
|
</linearGradient> |
||||
|
<linearGradient id="paint1_linear_66_104" x1="99.0202" y1="82.3728" x2="99.0202" y2="0.289293" gradientUnits="userSpaceOnUse"> |
||||
|
<stop stop-color="#CADCFF"/> |
||||
|
<stop offset="1" stop-color="white"/> |
||||
|
</linearGradient> |
||||
|
<linearGradient id="paint2_linear_66_104" x1="99.0632" y1="78.5268" x2="99.0632" y2="6.30677" gradientUnits="userSpaceOnUse"> |
||||
|
<stop stop-color="#07A7FD"/> |
||||
|
<stop offset="1" stop-color="#00DDF4"/> |
||||
|
</linearGradient> |
||||
|
<linearGradient id="paint3_linear_66_104" x1="99.0629" y1="76.1771" x2="99.0629" y2="3.95708" gradientUnits="userSpaceOnUse"> |
||||
|
<stop stop-color="#01EDF2"/> |
||||
|
<stop offset="1" stop-color="#08A3FF"/> |
||||
|
</linearGradient> |
||||
|
<linearGradient id="paint4_linear_66_104" x1="35.1888" y1="13.4594" x2="184.067" y2="20.0165" gradientUnits="userSpaceOnUse"> |
||||
|
<stop stop-color="#7ED140"/> |
||||
|
<stop offset="0.11" stop-color="#74C13B"/> |
||||
|
<stop offset="0.34" stop-color="#5B972E"/> |
||||
|
<stop offset="0.65" stop-color="#325319"/> |
||||
|
<stop offset="1"/> |
||||
|
</linearGradient> |
||||
|
</defs> |
||||
|
</svg> |
@ -0,0 +1,51 @@ |
|||||
|
<svg width="198" height="94" viewBox="0 0 198 94" fill="none" xmlns="http://www.w3.org/2000/svg"> |
||||
|
<g filter="url(#filter0_d_62_3)"> |
||||
|
<path d="M188.649 75.7216C188.465 75.8967 188.269 76.0595 188.06 76.2088C171.511 88.5762 27.8983 88.1393 7.85512 77.0322C6.98232 76.6133 6.25594 75.9787 5.75886 75.2006C-1.32062 61.7579 2.52254 21.1271 13.7762 12.3389C25.8756 2.92899 170.297 -1.33908 185.228 10.6586C196.243 19.4132 201.465 63.4214 188.649 75.7216Z" fill="url(#paint0_linear_62_3)"/> |
||||
|
</g> |
||||
|
<path d="M5.81368 72.529C12.6541 85.5516 174.544 86.5934 188.648 73.0667C201.52 60.7665 196.243 16.7415 185.283 7.97009C170.352 -3.99397 25.9304 0.257303 13.8493 9.65043C2.57734 18.4218 -1.2658 59.0526 5.81368 72.529Z" fill="url(#paint1_linear_62_3)"/> |
||||
|
<path d="M10.8713 66.6295C17.0865 78.3919 167.447 81.7526 180.246 69.4861C191.885 58.3118 187.16 18.3364 177.211 10.3716C163.641 -0.483467 30.1054 7.1453 19.0724 15.6815C8.83017 23.6631 4.43537 54.3798 10.8713 66.6295Z" fill="url(#paint2_radial_62_3)"/> |
||||
|
<path d="M11.3678 64.5472C17.5646 75.9399 167.043 76.7465 179.786 64.9001C191.37 54.1459 186.829 18.5393 176.917 10.8602C163.402 0.374815 30.2893 7.73473 19.3483 15.9012C9.21636 23.6644 4.96866 52.7344 11.3678 64.5472Z" fill="url(#paint3_linear_62_3)"/> |
||||
|
<path d="M13.2427 63.5391C19.2924 74.5957 165.534 75.3855 178.001 63.8919C189.347 53.4402 184.879 18.8923 175.188 11.4316C161.985 1.26547 31.7596 8.40694 21.0393 16.4726C11.0545 23.8661 6.95387 52.0287 13.2427 63.5391Z" fill="url(#paint4_linear_62_3)"/> |
||||
|
<path style="mix-blend-mode:screen" d="M20.6719 16.4554C20.6719 16.4554 122.653 -2.4485 175.556 11.7C178.81 15.8078 181.113 20.4792 182.323 25.4284C167.263 29.7983 151.627 32.2964 135.838 32.8555C108.623 33.9814 80.1763 19.9337 57.1909 17.8333C45.0721 16.5474 32.8654 16.0869 20.6719 16.4554Z" fill="url(#paint5_linear_62_3)"/> |
||||
|
<path d="M16.847 21.2277C18.4504 18.5512 20.9243 16.3963 23.9265 15.0608C28.8913 12.91 43.0135 10.7423 43.8226 11.2968C44.6317 11.8514 36.9454 14.3719 32.9551 15.7162C28.9649 17.0604 18.8697 22.2527 16.847 21.2277Z" fill="white"/> |
||||
|
<defs> |
||||
|
<filter id="filter0_d_62_3" x="0.557136" y="3.31949" width="197.234" height="89.8486" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"> |
||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/> |
||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/> |
||||
|
<feOffset dy="6.11371"/> |
||||
|
<feGaussianBlur stdDeviation="0.815162"/> |
||||
|
<feComposite in2="hardAlpha" operator="out"/> |
||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/> |
||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_62_3"/> |
||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_62_3" result="shape"/> |
||||
|
</filter> |
||||
|
<linearGradient id="paint0_linear_62_3" x1="99.208" y1="85.4339" x2="99.208" y2="3.31547" gradientUnits="userSpaceOnUse"> |
||||
|
<stop stop-color="#8B9AD1"/> |
||||
|
<stop offset="1" stop-color="#CEE0FF"/> |
||||
|
</linearGradient> |
||||
|
<linearGradient id="paint1_linear_62_3" x1="99.2077" y1="82.7623" x2="99.2077" y2="0.643783" gradientUnits="userSpaceOnUse"> |
||||
|
<stop stop-color="#CADCFF"/> |
||||
|
<stop offset="1" stop-color="white"/> |
||||
|
</linearGradient> |
||||
|
<radialGradient id="paint2_radial_62_3" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(100.385 72.1411) scale(69.2502 63.2818)"> |
||||
|
<stop stop-color="#FFBD00"/> |
||||
|
<stop offset="1" stop-color="#FF772C"/> |
||||
|
</radialGradient> |
||||
|
<linearGradient id="paint3_linear_62_3" x1="97.48" y1="73.453" x2="97.48" y2="5.68471" gradientUnits="userSpaceOnUse"> |
||||
|
<stop stop-color="#FFF300"/> |
||||
|
<stop offset="1" stop-color="#FF9700"/> |
||||
|
</linearGradient> |
||||
|
<linearGradient id="paint4_linear_62_3" x1="97.4793" y1="72.176" x2="97.4793" y2="6.40733" gradientUnits="userSpaceOnUse"> |
||||
|
<stop stop-color="#FFCC00"/> |
||||
|
<stop offset="1" stop-color="#FF9700"/> |
||||
|
</linearGradient> |
||||
|
<linearGradient id="paint5_linear_62_3" x1="20.6719" y1="19.6312" x2="182.323" y2="19.6312" gradientUnits="userSpaceOnUse"> |
||||
|
<stop stop-color="#FF9840"/> |
||||
|
<stop offset="0.1" stop-color="#EF8E3C"/> |
||||
|
<stop offset="0.29" stop-color="#C57531"/> |
||||
|
<stop offset="0.55" stop-color="#814D20"/> |
||||
|
<stop offset="0.88" stop-color="#241609"/> |
||||
|
<stop offset="1"/> |
||||
|
</linearGradient> |
||||
|
</defs> |
||||
|
</svg> |
@ -0,0 +1,3 @@ |
|||||
|
<svg width="26" height="25" viewBox="0 0 26 25" fill="none" xmlns="http://www.w3.org/2000/svg"> |
||||
|
<path d="M23.2676 0.871063H10.5279V4.85222H13.7129V6.44469H3.36184C2.00825 6.44469 0.973145 7.47979 0.973145 8.83339V17.5919C0.973145 18.9455 2.00825 19.9806 3.36184 19.9806H4.15807V24.0414L9.17434 19.9806H14.5091V14.407H23.2676C24.6212 14.407 25.6563 13.3719 25.6563 12.0183V3.25976C25.6563 1.90617 24.6212 0.871063 23.2676 0.871063ZM9.57245 16.7161L9.17434 15.4421H6.70602L6.22828 16.7161H4.31732L6.94489 9.62962H8.85584L11.4834 16.7161H9.57245ZM21.6752 10.4259V12.0183C20.6401 12.0183 19.5254 11.6998 18.5699 11.2221C17.6144 11.6998 16.4997 11.9387 15.3849 12.0183L15.3053 10.4259C15.8627 10.4259 16.4201 10.3462 16.9774 10.187C16.2608 9.47037 15.7831 8.59452 15.5442 7.63904H17.2163C17.4552 8.35565 17.9329 8.91301 18.4903 9.39075C19.3661 8.67414 19.9235 7.63904 20.0031 6.44469H15.2257V4.85222H17.6144V3.25976H19.2069V4.85222H21.8344L21.9141 5.64846C21.9937 7.32054 21.3567 8.99263 20.1623 10.187C20.7197 10.3462 21.1974 10.4259 21.6752 10.4259Z" fill="#847AC4"/> |
||||
|
</svg> |
77
assets/images/start.svg
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -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<String?> redirect(BuildContext context, GoRouterState state) async { |
|
||||
if (AuthStorage.isLogin()) { |
|
||||
return Routes.homePage; |
|
||||
} else { |
|
||||
return null; |
|
||||
} |
|
||||
} |
|
||||
} |
|
@ -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<String?> redirect(BuildContext context, GoRouterState state) async { |
||||
|
if (LocalStorage.readData(key: MyConstants.selectLanguage).isNotEmpty) { |
||||
|
return Routes.homePage; |
||||
|
} else { |
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
|
} |
@ -1,13 +1,17 @@ |
|||||
class LanguageParams { |
class LanguageParams { |
||||
int? id; |
|
||||
|
String? code; |
||||
|
|
||||
LanguageParams({this.id}); |
|
||||
|
LanguageParams({this.code}); |
||||
|
|
||||
LanguageParams copyWith({ |
LanguageParams copyWith({ |
||||
int? id, |
|
||||
|
String? code, |
||||
}) { |
}) { |
||||
return LanguageParams( |
return LanguageParams( |
||||
id: id ?? this.id, |
|
||||
|
code: code ?? this.code, |
||||
); |
); |
||||
} |
} |
||||
|
|
||||
|
Map<String, dynamic> get toHeader => { |
||||
|
if (code != null) 'HTTP_X_USER_LANGUAGE': code, |
||||
|
}; |
||||
} |
} |
@ -0,0 +1,18 @@ |
|||||
|
import 'dart:ui'; |
||||
|
|
||||
|
import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart'; |
||||
|
|
||||
|
enum ButtonType { |
||||
|
type1, |
||||
|
type2; |
||||
|
|
||||
|
static Map<ButtonType, String> get image => { |
||||
|
type1: MyAssets.button, |
||||
|
type2: MyAssets.button2, |
||||
|
}; |
||||
|
|
||||
|
static Map<ButtonType, Color> get textColor => { |
||||
|
type1: Color(0XFF1D6EFF), |
||||
|
type2: Color(0XFFD93D16), |
||||
|
}; |
||||
|
} |
@ -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], |
||||
|
), |
||||
|
), |
||||
|
), |
||||
|
], |
||||
|
), |
||||
|
), |
||||
|
); |
||||
|
} |
||||
|
} |
@ -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<String, dynamic> json) { |
|
||||
return LanguageModel( |
|
||||
id: json['id'], |
|
||||
); |
|
||||
} |
|
||||
} |
|
@ -1,14 +1,17 @@ |
|||||
import 'package:equatable/equatable.dart'; |
import 'package:equatable/equatable.dart'; |
||||
|
|
||||
class LanguageEntity extends Equatable { |
class LanguageEntity extends Equatable { |
||||
final int? id; |
|
||||
|
final String? title; |
||||
|
final String? code; |
||||
|
|
||||
const LanguageEntity({ |
const LanguageEntity({ |
||||
this.id, |
|
||||
|
this.title, |
||||
|
this.code, |
||||
}); |
}); |
||||
|
|
||||
@override |
@override |
||||
List<Object?> get props => [ |
List<Object?> get props => [ |
||||
id, |
|
||||
]; |
|
||||
|
title, |
||||
|
code, |
||||
|
]; |
||||
} |
} |
@ -1,8 +1,8 @@ |
|||||
import 'package:hadi_hoda_flutter/core/error_handler/my_exception.dart'; |
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/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/core/utils/data_state.dart'; |
||||
import 'package:hadi_hoda_flutter/features/language/domain/entity/language_entity.dart'; |
|
||||
|
|
||||
abstract class ILanguageRepository { |
abstract class ILanguageRepository { |
||||
Future<DataState<LanguageEntity, MyException>> getData({required LanguageParams params}); |
|
||||
|
Future<DataState<NoParams, MyException>> saveLevels({required LanguageParams params}); |
||||
} |
} |
@ -1,17 +1,17 @@ |
|||||
import 'package:hadi_hoda_flutter/core/error_handler/my_exception.dart'; |
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/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/usecase/usecase.dart'; |
||||
import 'package:hadi_hoda_flutter/core/utils/data_state.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'; |
import 'package:hadi_hoda_flutter/features/language/domain/repository/language_repository.dart'; |
||||
|
|
||||
class GetLanguageUseCase implements UseCase<LanguageEntity, LanguageParams> { |
|
||||
|
class SaveLevelsUseCase implements UseCase<NoParams, LanguageParams> { |
||||
final ILanguageRepository repository; |
final ILanguageRepository repository; |
||||
|
|
||||
const GetLanguageUseCase(this.repository); |
|
||||
|
const SaveLevelsUseCase(this.repository); |
||||
|
|
||||
@override |
@override |
||||
Future<DataState<LanguageEntity, MyException>> call(LanguageParams params) { |
|
||||
return repository.getData(params: params); |
|
||||
|
Future<DataState<NoParams, MyException>> call(LanguageParams params) { |
||||
|
return repository.saveLevels(params: params); |
||||
} |
} |
||||
} |
} |
@ -1,41 +1,60 @@ |
|||||
import 'dart:async'; |
import 'dart:async'; |
||||
import 'package:bloc/bloc.dart'; |
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/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/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_event.dart'; |
||||
import 'package:hadi_hoda_flutter/features/language/presentation/bloc/language_state.dart'; |
import 'package:hadi_hoda_flutter/features/language/presentation/bloc/language_state.dart'; |
||||
|
|
||||
class LanguageBloc extends Bloc<LanguageEvent, LanguageState> { |
class LanguageBloc extends Bloc<LanguageEvent, LanguageState> { |
||||
/// ------------constructor------------ |
/// ------------constructor------------ |
||||
LanguageBloc( |
LanguageBloc( |
||||
this._getLanguageUseCase, |
|
||||
|
this._saveLevelsUseCase, |
||||
) : super(const LanguageState()) { |
) : super(const LanguageState()) { |
||||
on<GetLanguageEvent>(_getLanguageEvent); |
|
||||
|
on<ChangeLanguageEvent>(_changeLanguageEvent); |
||||
|
on<SaveLevelsEvent>(_saveLevelsEvent); |
||||
} |
} |
||||
|
|
||||
/// ------------UseCases------------ |
/// ------------UseCases------------ |
||||
final GetLanguageUseCase _getLanguageUseCase; |
|
||||
|
final SaveLevelsUseCase _saveLevelsUseCase; |
||||
|
|
||||
/// ------------Variables------------ |
/// ------------Variables------------ |
||||
|
final List<LanguageEntity> languages = [ |
||||
|
LanguageEntity(title: 'Persian (فارسی)', code: 'fa'), |
||||
|
LanguageEntity(title: 'English (English)', code: 'en'), |
||||
|
LanguageEntity(title: 'Arabic (عربی)', code: 'ar'), |
||||
|
]; |
||||
|
|
||||
/// ------------Controllers------------ |
/// ------------Controllers------------ |
||||
|
|
||||
/// ------------Functions------------ |
/// ------------Functions------------ |
||||
|
FutureOr<void> _changeLanguageEvent( |
||||
|
ChangeLanguageEvent event, |
||||
|
Emitter<LanguageState> emit, |
||||
|
) { |
||||
|
emit(state.copyWith(selectedLang: event.lang)); |
||||
|
} |
||||
|
|
||||
/// ------------Api Calls------------ |
/// ------------Api Calls------------ |
||||
FutureOr<void> _getLanguageEvent(event, emit) async { |
|
||||
await _getLanguageUseCase(event.languageParams).then( |
|
||||
(value) { |
|
||||
value.fold( |
|
||||
(data) { |
|
||||
emit(state.copyWith(getLanguageStatus: BaseComplete<LanguageEntity>(data))); |
|
||||
}, |
|
||||
(error) { |
|
||||
emit(state.copyWith(getLanguageStatus: BaseError(error.errorMessage))); |
|
||||
}, |
|
||||
); |
|
||||
}, |
|
||||
); |
|
||||
|
FutureOr<void> _saveLevelsEvent( |
||||
|
SaveLevelsEvent event, |
||||
|
Emitter<LanguageState> 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())); |
||||
|
}, |
||||
|
), |
||||
|
); |
||||
} |
} |
||||
} |
} |
@ -1,5 +1,16 @@ |
|||||
|
import 'package:hadi_hoda_flutter/features/language/domain/entity/language_entity.dart'; |
||||
|
|
||||
sealed class LanguageEvent { |
sealed class LanguageEvent { |
||||
const LanguageEvent(); |
const LanguageEvent(); |
||||
} |
} |
||||
|
|
||||
class GetLanguageEvent extends LanguageEvent {} |
|
||||
|
class ChangeLanguageEvent extends LanguageEvent { |
||||
|
final LanguageEntity lang; |
||||
|
|
||||
|
const ChangeLanguageEvent(this.lang); |
||||
|
} |
||||
|
|
||||
|
class SaveLevelsEvent extends LanguageEvent { |
||||
|
const SaveLevelsEvent(); |
||||
|
} |
||||
|
|
@ -1,15 +1,22 @@ |
|||||
import 'package:hadi_hoda_flutter/core/status/base_status.dart'; |
import 'package:hadi_hoda_flutter/core/status/base_status.dart'; |
||||
|
import 'package:hadi_hoda_flutter/features/language/domain/entity/language_entity.dart'; |
||||
|
|
||||
class LanguageState { |
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({ |
LanguageState copyWith({ |
||||
BaseStatus? getLanguageStatus, |
|
||||
|
BaseStatus? saveLevelsStatus, |
||||
|
LanguageEntity? selectedLang, |
||||
}) { |
}) { |
||||
return LanguageState( |
return LanguageState( |
||||
getLanguageStatus: getLanguageStatus ?? this.getLanguageStatus, |
|
||||
|
saveLevelsStatus: saveLevelsStatus ?? this.saveLevelsStatus, |
||||
|
selectedLang: selectedLang ?? this.selectedLang, |
||||
); |
); |
||||
} |
} |
||||
} |
} |
@ -1,10 +1,157 @@ |
|||||
|
import 'package:flutter/cupertino.dart'; |
||||
import 'package:flutter/material.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 { |
class LanguagePage extends StatelessWidget { |
||||
const LanguagePage({super.key}); |
const LanguagePage({super.key}); |
||||
|
|
||||
@override |
@override |
||||
Widget build(BuildContext context) { |
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<LanguageBloc>().languages.length, |
||||
|
(index) => BlocBuilder<LanguageBloc, LanguageState>( |
||||
|
buildWhen: (previous, current) => |
||||
|
previous.selectedLang.code != current.selectedLang.code, |
||||
|
builder: (context, state) { |
||||
|
final LanguageBloc languageBloc = context.read<LanguageBloc>(); |
||||
|
return ListTile( |
||||
|
selected: state.selectedLang.code == |
||||
|
languageBloc.languages[index].code, |
||||
|
onTap: () { |
||||
|
languageBloc.add( |
||||
|
ChangeLanguageEvent(languageBloc.languages[index])); |
||||
|
}, |
||||
|
title: Text(context.read<LanguageBloc>().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<LanguageBloc, LanguageState>( |
||||
|
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<LanguageBloc>().add(SaveLevelsEvent()), |
||||
|
title: context.translate.select, |
||||
|
); |
||||
} |
} |
||||
} |
} |
@ -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<LevelEntity>? levels; |
||||
|
|
||||
|
TotalDataEntity({ |
||||
|
this.code, |
||||
|
this.levels, |
||||
|
}); |
||||
|
} |
@ -1,5 +1,7 @@ |
|||||
{ |
{ |
||||
"about_us": "About us", |
"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.", |
"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" |
||||
} |
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue