Browse Source

fix: get data based on selected language

pull/13/head
AmirrezaChegini 4 days ago
parent
commit
9752aff871
  1. BIN
      assets/images/error.png
  2. 1
      lib/common_ui/resources/my_assets.dart
  3. 10
      lib/common_ui/resources/my_text_style.dart
  4. 16
      lib/common_ui/theme/my_theme.dart
  5. 1
      lib/core/constants/my_constants.dart
  6. 21
      lib/core/middleware/language_middleware.dart
  7. 4
      lib/core/params/language_params.dart
  8. 7
      lib/core/routers/my_routes.dart
  9. 2
      lib/core/utils/context_provider.dart
  10. 5
      lib/core/utils/convert_size.dart
  11. 4
      lib/core/utils/my_image.dart
  12. 6
      lib/core/widgets/about_us_dialog/about_us_dialog.dart
  13. 4
      lib/core/widgets/answer_box/styles/picture_box.dart
  14. 6
      lib/core/widgets/button/my_button.dart
  15. 59
      lib/core/widgets/error/error_state.dart
  16. 6
      lib/core/widgets/showcase/question_showcase.dart
  17. 4
      lib/features/home/presentation/bloc/home_bloc.dart
  18. 9
      lib/features/home/presentation/ui/home_page.dart
  19. 61
      lib/features/intro/data/datasource/intro_datasource.dart
  20. 19
      lib/features/intro/data/repository_impl/intro_repository_impl.dart
  21. 7
      lib/features/intro/domain/entities/download_entity.dart
  22. 4
      lib/features/intro/domain/repository/intro_repository.dart
  23. 3
      lib/features/intro/domain/usecases/loading_stream_usecase.dart
  24. 16
      lib/features/intro/domain/usecases/save_levels_usecase.dart
  25. 41
      lib/features/intro/presentation/bloc/intro_bloc.dart
  26. 1
      lib/features/intro/presentation/bloc/intro_event.dart
  27. 56
      lib/features/intro/presentation/ui/intro_page.dart
  28. 11
      lib/features/intro/presentation/ui/widgets/intro_loading_widget.dart
  29. 46
      lib/features/language/data/datasource/language_datasource.dart
  30. 29
      lib/features/language/data/repository_impl/language_repository_impl.dart
  31. 8
      lib/features/language/domain/repository/language_repository.dart
  32. 17
      lib/features/language/domain/usecases/save_levels_usecase.dart
  33. 50
      lib/features/language/presentation/bloc/language_bloc.dart
  34. 5
      lib/features/language/presentation/bloc/language_event.dart
  35. 24
      lib/features/language/presentation/ui/language_page.dart
  36. 4
      lib/features/level/presentation/ui/widgets/level_widget.dart
  37. 8
      lib/features/question/presentation/ui/question_page.dart
  38. 4
      lib/features/question/presentation/ui/widgets/refresh_button.dart
  39. 9
      lib/init_bindings.dart
  40. 7
      lib/l10n/app_en.arb
  41. 30
      lib/l10n/app_localizations.dart
  42. 16
      lib/l10n/app_localizations_en.dart

BIN
assets/images/error.png

After

Width: 332  |  Height: 222  |  Size: 14 KiB

1
lib/common_ui/resources/my_assets.dart

@ -38,4 +38,5 @@ class MyAssets {
static const String homeButton = 'assets/images/home_button.png';
static const String doneRounded = 'assets/images/done_rounded.svg';
static const String lang = 'assets/images/lang.svg';
static const String error = 'assets/images/error.png';
}

10
lib/common_ui/resources/my_text_style.dart

@ -18,6 +18,11 @@ class DinoKids {
fontSize: 26,
fontWeight: FontWeight.w400,
);
static const TextStyle regular35 = TextStyle(
fontFamily: fontFamily,
fontSize: 35,
fontWeight: FontWeight.w400,
);
static const TextStyle regular45 = TextStyle(
fontFamily: fontFamily,
fontSize: 45,
@ -43,6 +48,11 @@ class Marhey {
fontSize: 16,
fontWeight: FontWeight.w500,
);
static const TextStyle medium22 = TextStyle(
fontFamily: fontFamily,
fontSize: 22,
fontWeight: FontWeight.w500,
);
/// Semi Bold
static const TextStyle semiBold17 = TextStyle(

16
lib/common_ui/theme/my_theme.dart

@ -1,8 +1,7 @@
import 'package:hadi_hoda_flutter/core/utils/context_provider.dart';
import 'package:flutter/material.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_colors.dart';
enum ColorsName { primaryColor, noColor, backgroundDialog }
enum ColorsName { primaryColor, backgroundDialog }
class MyTheme {
static const MyTheme _i = MyTheme._internal();
@ -14,25 +13,12 @@ class MyTheme {
static final ThemeData dark = ThemeData(brightness: Brightness.dark);
static Map<ColorsName, Color> get lightColors => {
ColorsName.noColor: MyColors.transparent,
ColorsName.primaryColor: MyColors.white,
ColorsName.backgroundDialog: MyColors.purple,
};
static Map<ColorsName, Color> get darkColors => {
ColorsName.noColor: MyColors.transparent,
ColorsName.primaryColor: MyColors.black,
ColorsName.backgroundDialog: MyColors.purple,
};
}
extension ThemeExtension on BuildContext {
Map<ColorsName, Color> get customColors =>
Theme.of(ContextProvider.context!).brightness == Brightness.dark
? MyTheme.darkColors
: MyTheme.lightColors;
Color get primaryColor => customColors[ColorsName.primaryColor]!;
Color get noColor => customColors[ColorsName.noColor]!;
Color get backgroundDialog => customColors[ColorsName.backgroundDialog]!;
}

1
lib/core/constants/my_constants.dart

@ -9,4 +9,5 @@ class MyConstants {
static const String downloadCompleted = 'DOWNLOAD_COMPLETED';
static const String extractCompleted = 'EXTRACT_COMPLETED';
static const String selectLanguage = 'SELECT_LANGUAGE';
static const String firstLanguagePage = 'FIRST_LANGUAGE_PAGE';
}

21
lib/core/middleware/language_middleware.dart

@ -1,21 +0,0 @@
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;
}
}
}

4
lib/core/params/language_params.dart

@ -11,7 +11,7 @@ class LanguageParams {
);
}
Map<String, dynamic> get toHeader => {
if (code != null) 'HTTP_X_USER_LANGUAGE': code,
Map<String, dynamic> get toQuery => {
if (code != null) 'lang': code,
};
}

7
lib/core/routers/my_routes.dart

@ -1,12 +1,12 @@
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/bloc/language_event.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';
@ -36,16 +36,15 @@ GoRouter get appPages => GoRouter(
name: Routes.introPage,
path: Routes.introPage,
builder: (context, state) => BlocProvider(
create: (context) => IntroBloc(locator(), locator()),
create: (context) => IntroBloc(locator(), locator(), locator()),
child: const IntroPage(),
),
),
GoRoute(
name: Routes.languagePage,
path: Routes.languagePage,
redirect: LanguageMiddleware.redirect,
builder: (context, state) => BlocProvider(
create: (context) => LanguageBloc(locator()),
create: (context) => LanguageBloc()..add(InitLanguageEvent()),
child: const LanguagePage(),
),
),

2
lib/core/utils/context_provider.dart

@ -6,5 +6,5 @@ class ContextProvider {
factory ContextProvider() => _i;
static GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
static BuildContext? context = navigatorKey.currentContext;
static BuildContext context = navigatorKey.currentContext!;
}

5
lib/core/utils/convert_size.dart

@ -0,0 +1,5 @@
extension ConvertSize on double? {
String get toMB {
return this == null ? '0.0' : (this! / (1024 * 1024)).toStringAsFixed(1);
}
}

4
lib/core/utils/my_image.dart

@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:hadi_hoda_flutter/common_ui/theme/my_theme.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_colors.dart';
class MyImage extends StatelessWidget {
const MyImage({
@ -32,7 +32,7 @@ class MyImage extends StatelessWidget {
width: size,
height: size,
colorFilter: color != null
? ColorFilter.mode(color ?? context.primaryColor, BlendMode.srcIn)
? ColorFilter.mode(color!, BlendMode.srcIn)
: null,
);
}

6
lib/core/widgets/about_us_dialog/about_us_dialog.dart

@ -3,8 +3,8 @@ import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_colors.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart';
import 'package:hadi_hoda_flutter/common_ui/theme/my_theme.dart';
import 'package:hadi_hoda_flutter/core/utils/check_platform.dart';
import 'package:hadi_hoda_flutter/core/utils/my_image.dart';
import 'package:hadi_hoda_flutter/core/utils/my_localization.dart';
@ -14,7 +14,7 @@ Future<void> showAboutUsDialog({required BuildContext context}) async {
await showDialog(
context: context,
builder: (context) => AboutUsDialog(),
barrierColor: context.backgroundDialog.withValues(alpha: 0.82),
barrierColor: MyColors.purple.withValues(alpha: 0.82),
useSafeArea: false,
);
}
@ -25,7 +25,7 @@ class AboutUsDialog extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: context.noColor,
backgroundColor: MyColors.transparent,
body: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 6, sigmaY: 6),
child: Center(

4
lib/core/widgets/answer_box/styles/picture_box.dart

@ -1,9 +1,9 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_colors.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_spaces.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart';
import 'package:hadi_hoda_flutter/common_ui/theme/my_theme.dart';
class AnswerPictureBox extends StatelessWidget {
const AnswerPictureBox({super.key, required this.selected, required this.image, required this.index});
@ -49,7 +49,7 @@ class AnswerPictureBox extends StatelessWidget {
child: Text(
'$index',
style: Marhey.semiBold17.copyWith(
color: context.primaryColor,
color: MyColors.white,
),
),
),

6
lib/core/widgets/button/my_button.dart

@ -1,8 +1,8 @@
import 'package:flutter/material.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_colors.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_spaces.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart';
import 'package:hadi_hoda_flutter/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';
@ -25,8 +25,8 @@ class MyButton extends StatelessWidget {
width: 194,
child: InkWell(
onTap: onTap,
highlightColor: context.noColor,
splashColor: context.noColor,
highlightColor: MyColors.transparent,
splashColor: MyColors.transparent,
child: Stack(
alignment: Alignment.center,
children: [

59
lib/core/widgets/error/error_state.dart

@ -0,0 +1,59 @@
import 'package:flutter/material.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_colors.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_spaces.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart';
import 'package:hadi_hoda_flutter/core/utils/gap.dart';
import 'package:hadi_hoda_flutter/core/utils/my_image.dart';
import 'package:hadi_hoda_flutter/core/utils/my_localization.dart';
class ErrorState extends StatelessWidget {
const ErrorState({super.key, this.onTap});
final VoidCallback? onTap;
@override
Widget build(BuildContext context) {
return Column(
children: [
Spacer(),
Text(
context.translate.lost_connection,
style: DinoKids.regular45.copyWith(color: MyColors.white),
),
MyImage(image: MyAssets.error),
MySpaces.s40.gapHeight,
Text(
context.translate.connected_to_internet,
textAlign: TextAlign.center,
style: Marhey.medium12.copyWith(color: MyColors.white),
),
Spacer(),
SizedBox(
height: 84,
width: 194,
child: InkWell(
onTap: onTap,
highlightColor: MyColors.transparent,
splashColor: MyColors.transparent,
child: Stack(
alignment: Alignment.center,
children: [
MyImage(image: MyAssets.button),
PositionedDirectional(
top: MySpaces.s8,
child: Text(
context.translate.try_again,
style: DinoKids.regular35.copyWith(
color: Color(0XFF1D6EFF),
),
),
),
],
),
),
),
],
);
}
}

6
lib/core/widgets/showcase/question_showcase.dart

@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_colors.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart';
import 'package:hadi_hoda_flutter/common_ui/theme/my_theme.dart';
import 'package:hadi_hoda_flutter/core/utils/my_image.dart';
import 'package:hadi_hoda_flutter/core/utils/screen_size.dart';
import 'package:showcaseview/showcaseview.dart';
@ -26,10 +26,10 @@ class QuestionShowcase extends StatelessWidget {
targetShapeBorder: CircleBorder(),
tooltipBackgroundColor: Colors.transparent,
disableMovingAnimation: true,
textColor: context.primaryColor,
textColor: MyColors.white,
descriptionTextAlign: TextAlign.center,
descTextStyle: Marhey.bold12.copyWith(
color: context.primaryColor,
color: MyColors.white,
),
disableScaleAnimation: true,
tooltipPadding: EdgeInsets.only(top: 60),

4
lib/features/home/presentation/bloc/home_bloc.dart

@ -29,6 +29,10 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
context.pushNamed(Routes.levelPage);
}
void goToLanguagePage(BuildContext context){
context.pushNamed(Routes.languagePage);
}
/// ------------Api Calls------------
FutureOr<void> _getHomeEvent(event, emit) async {
await _getHomeUseCase(event.homeParams).then(

9
lib/features/home/presentation/ui/home_page.dart

@ -1,7 +1,7 @@
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/theme/my_theme.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_colors.dart';
import 'package:hadi_hoda_flutter/core/utils/check_platform.dart';
import 'package:hadi_hoda_flutter/core/utils/my_image.dart';
import 'package:hadi_hoda_flutter/core/utils/screen_size.dart';
@ -13,7 +13,7 @@ class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(backgroundColor: context.noColor),
appBar: AppBar(backgroundColor: MyColors.transparent),
extendBodyBehindAppBar: true,
body: DecoratedBox(
decoration: BoxDecoration(
@ -70,10 +70,13 @@ class HomePage extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
MyImage(
InkWell(
onTap: () => context.read<HomeBloc>().goToLanguagePage(context),
child: MyImage(
image: MyAssets.language,
size: checkSize(context: context, tablet: 120),
),
),
InkWell(
child: MyImage(
image: MyAssets.button,

61
lib/features/intro/data/datasource/intro_datasource.dart

@ -6,31 +6,48 @@ 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/response/base_response.dart';
import 'package:hadi_hoda_flutter/core/utils/local_storage.dart';
import 'package:hadi_hoda_flutter/core/utils/storage_path.dart';
import 'package:hadi_hoda_flutter/features/intro/domain/entities/download_entity.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 IIntroDatasource {
Future<void> getFiles();
Stream<double> loadingStream();
Future<void> saveLevels();
Stream<DownloadEntity> loadingStream();
}
class IntroDatasourceImpl implements IIntroDatasource {
final IHttpRequest httpRequest;
final StreamController<double> streamController = StreamController<double>.broadcast();
final StreamController<DownloadEntity> streamController = StreamController<DownloadEntity>.broadcast();
IntroDatasourceImpl(this.httpRequest);
@override
Future<void> getFiles() async {
final String filePath = '${StoragePath.documentDir.path}/files.zip';
final String selectedLanguage =
LocalStorage.readData(key: MyConstants.selectLanguage).isEmpty
? 'fa'
: LocalStorage.readData(key: MyConstants.selectLanguage);
if (LocalStorage.readData(key: MyConstants.downloadCompleted) != 'true') {
await httpRequest.download(
urlPath: MyApi.files,
savePath: filePath,
queryParameters: {
'lang': selectedLanguage,
},
onReceive: (count, total) {
double percent = ((count / total) * 100);
streamController.add(percent);
streamController.add(DownloadEntity(
count: count / 1,
total: total / 1,
percent: (count / total) * 100,
));
},
).then((value) async {
await LocalStorage.saveData(
@ -43,12 +60,11 @@ class IntroDatasourceImpl implements IIntroDatasource {
try{
if (LocalStorage.readData(key: MyConstants.extractCompleted) != 'true') {
final File file = File(filePath);
final Directory directory = Directory('${StoragePath.documentDir.path}/files/');
final Directory directory = Directory('${StoragePath.documentDir.path}/$selectedLanguage/files/');
await ZipFile.extractToDirectory(
zipFile: file,
destinationDir: directory,
onExtracting: (zipEntry, progress) {
streamController.add(progress);
return ZipFileOperation.includeItem;
},
).then((value) async {
@ -61,9 +77,9 @@ class IntroDatasourceImpl implements IIntroDatasource {
]);
});
} else {
streamController.add(50);
streamController.add(DownloadEntity(percent: 50));
await Future.delayed(Duration(milliseconds: 150));
streamController.add(100);
streamController.add(DownloadEntity(percent: 100));
}
} catch (e){
throw MyException(errorMessage: '$e');
@ -71,5 +87,32 @@ class IntroDatasourceImpl implements IIntroDatasource {
}
@override
Stream<double> loadingStream() => streamController.stream;
Future<void> saveLevels() async {
final String selectedLanguage =
LocalStorage.readData(key: MyConstants.selectLanguage).isEmpty
? 'fa'
: LocalStorage.readData(key: MyConstants.selectLanguage);
final Box<TotalDataEntity> data = Hive.box(MyConstants.levelBox);
final TotalDataEntity findData = data.values.singleWhere(
(e) => e.code == selectedLanguage,
orElse: () => TotalDataEntity(),
);
if (findData.code != selectedLanguage) {
final response = await httpRequest.get(
path: MyApi.levels,
queryParameters: {'lang': selectedLanguage},
);
final List<LevelEntity> levels = BaseResponse.getDataList<LevelEntity>(
response?['result'],
(json) => LevelModel.fromJson(json),
);
await Future.wait([
data.add(TotalDataEntity(code: selectedLanguage, levels: levels)),
]);
}
}
@override
Stream<DownloadEntity> loadingStream() => streamController.stream;
}

19
lib/features/intro/data/repository_impl/intro_repository_impl.dart

@ -3,6 +3,7 @@ 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/intro/data/datasource/intro_datasource.dart';
import 'package:hadi_hoda_flutter/features/intro/domain/entities/download_entity.dart';
import 'package:hadi_hoda_flutter/features/intro/domain/repository/intro_repository.dart';
class IntroRepositoryImpl implements IIntroRepository {
@ -27,7 +28,23 @@ class IntroRepositoryImpl implements IIntroRepository {
}
@override
Stream<double> loadingStream() {
Future<DataState<NoParams, MyException>> saveLevels() async {
try {
await datasource.saveLevels();
return DataState.success(NoParams());
} on MyException catch (e) {
return DataState.error(e);
} catch (e) {
if (kDebugMode) {
rethrow;
} else {
return DataState.error(MyException(errorMessage: '$e'));
}
}
}
@override
Stream<DownloadEntity> loadingStream() {
return datasource.loadingStream();
}
}

7
lib/features/intro/domain/entities/download_entity.dart

@ -0,0 +1,7 @@
class DownloadEntity {
final double? count;
final double? total;
final double? percent;
const DownloadEntity({this.count, this.total, this.percent});
}

4
lib/features/intro/domain/repository/intro_repository.dart

@ -1,8 +1,10 @@
import 'package:hadi_hoda_flutter/core/error_handler/my_exception.dart';
import 'package:hadi_hoda_flutter/core/params/no_params.dart';
import 'package:hadi_hoda_flutter/core/utils/data_state.dart';
import 'package:hadi_hoda_flutter/features/intro/domain/entities/download_entity.dart';
abstract class IIntroRepository {
Future<DataState<NoParams, MyException>> getFiles();
Stream<double> loadingStream();
Future<DataState<NoParams, MyException>> saveLevels();
Stream<DownloadEntity> loadingStream();
}

3
lib/features/intro/domain/usecases/loading_stream_usecase.dart

@ -1,3 +1,4 @@
import 'package:hadi_hoda_flutter/features/intro/domain/entities/download_entity.dart';
import 'package:hadi_hoda_flutter/features/intro/domain/repository/intro_repository.dart';
class LoadingStreamUseCase {
@ -5,7 +6,7 @@ class LoadingStreamUseCase {
const LoadingStreamUseCase(this.repository);
Stream<double> call() {
Stream<DownloadEntity> call() {
return repository.loadingStream();
}
}

16
lib/features/intro/domain/usecases/save_levels_usecase.dart

@ -0,0 +1,16 @@
import 'package:hadi_hoda_flutter/core/error_handler/my_exception.dart';
import 'package:hadi_hoda_flutter/core/params/no_params.dart';
import 'package:hadi_hoda_flutter/core/usecase/usecase.dart';
import 'package:hadi_hoda_flutter/core/utils/data_state.dart';
import 'package:hadi_hoda_flutter/features/intro/domain/repository/intro_repository.dart';
class SaveLevelsUseCase implements UseCase<NoParams, NoParams> {
final IIntroRepository repository;
const SaveLevelsUseCase(this.repository);
@override
Future<DataState<NoParams, MyException>> call(NoParams params) {
return repository.saveLevels();
}
}

41
lib/features/intro/presentation/bloc/intro_bloc.dart

@ -2,29 +2,39 @@ import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:go_router/go_router.dart';
import 'package:hadi_hoda_flutter/core/constants/my_constants.dart';
import 'package:hadi_hoda_flutter/core/params/no_params.dart';
import 'package:hadi_hoda_flutter/core/routers/my_routes.dart';
import 'package:hadi_hoda_flutter/core/status/base_status.dart';
import 'package:hadi_hoda_flutter/core/utils/context_provider.dart';
import 'package:hadi_hoda_flutter/core/utils/local_storage.dart';
import 'package:hadi_hoda_flutter/features/intro/domain/entities/download_entity.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/intro/domain/usecases/save_levels_usecase.dart';
import 'package:hadi_hoda_flutter/features/intro/presentation/bloc/intro_event.dart';
import 'package:hadi_hoda_flutter/features/intro/presentation/bloc/intro_state.dart';
class IntroBloc extends Bloc<IntroEvent, IntroState> {
/// ------------constructor------------
IntroBloc(this._getFilesUseCase, this._loadingStreamUseCase)
IntroBloc(
this._getFilesUseCase,
this._loadingStreamUseCase,
this._saveLevelsUseCase,
)
: super(const IntroState()) {
on<GetFilesEvent>(_getFilesEvent);
on<SaveLevelsEvent>(_saveLevelsEvent);
loadingStream = _loadingStreamUseCase();
}
/// ------------UseCases------------
final GetFilesUseCase _getFilesUseCase;
final SaveLevelsUseCase _saveLevelsUseCase;
final LoadingStreamUseCase _loadingStreamUseCase;
/// ------------Variables------------
Stream<double> loadingStream = Stream.empty();
Stream<DownloadEntity> loadingStream = Stream.empty();
/// ------------Controllers------------
@ -35,19 +45,38 @@ class IntroBloc extends Bloc<IntroEvent, IntroState> {
GetFilesEvent event,
Emitter<IntroState> emit,
) async {
emit(state.copyWith(getFilesStatus: BaseInit()));
await _getFilesUseCase(NoParams()).then((value) {
value.fold(
(data) async {
await Future.delayed(
Duration(milliseconds: 300), () {
ContextProvider.context!.goNamed(Routes.languagePage);
add(SaveLevelsEvent());
},
(error) async {
emit(state.copyWith(getFilesStatus: BaseError(error.errorMessage)));
},
);
});
}
FutureOr<void> _saveLevelsEvent(SaveLevelsEvent event,
Emitter<IntroState> emit) async {
await _saveLevelsUseCase(NoParams()).then((value) =>
value.fold(
(data) async {
if(LocalStorage.readData(key: MyConstants.firstLanguagePage) != 'true'){
ContextProvider.context.goNamed(Routes.languagePage);
} else {
await Future.delayed(Duration(milliseconds: 500), () {
if (ContextProvider.context.mounted) {
ContextProvider.context.goNamed(Routes.homePage);
}
});
}
},
(error) {
emit(state.copyWith(getFilesStatus: BaseError(error.errorMessage)));
},
),
);
});
}
}

1
lib/features/intro/presentation/bloc/intro_event.dart

@ -2,3 +2,4 @@ sealed class IntroEvent {
const IntroEvent();
}
class GetFilesEvent extends IntroEvent {}
class SaveLevelsEvent extends IntroEvent {}

56
lib/features/intro/presentation/ui/intro_page.dart

@ -1,11 +1,19 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_colors.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_spaces.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart';
import 'package:hadi_hoda_flutter/core/status/base_status.dart';
import 'package:hadi_hoda_flutter/core/utils/convert_size.dart';
import 'package:hadi_hoda_flutter/core/utils/my_image.dart';
import 'package:hadi_hoda_flutter/core/utils/my_localization.dart';
import 'package:hadi_hoda_flutter/core/utils/screen_size.dart';
import 'package:hadi_hoda_flutter/core/widgets/error/error_state.dart';
import 'package:hadi_hoda_flutter/features/intro/domain/entities/download_entity.dart';
import 'package:hadi_hoda_flutter/features/intro/presentation/bloc/intro_bloc.dart';
import 'package:hadi_hoda_flutter/features/intro/presentation/bloc/intro_event.dart';
import 'package:hadi_hoda_flutter/features/intro/presentation/bloc/intro_state.dart';
import 'package:hadi_hoda_flutter/features/intro/presentation/ui/widgets/intro_loading_widget.dart';
class IntroPage extends StatefulWidget {
@ -47,12 +55,31 @@ class _IntroPageState extends State<IntroPage> {
),
),
),
child: Stack(
child: BlocBuilder<IntroBloc, IntroState>(
buildWhen: (previous, current) =>
previous.getFilesStatus != current.getFilesStatus,
builder: (context, state) {
if (state.getFilesStatus is BaseError) {
return Padding(
padding: EdgeInsets.symmetric(
vertical: MediaQuery.viewPaddingOf(context).bottom + MySpaces.s16,
horizontal: 60,
),
child: ErrorState(
onTap: () => context.read<IntroBloc>().add(GetFilesEvent()),
),
);
} else {
return Stack(
alignment: Alignment.center,
children: [
_image(),
_text(context),
_loading(context),
],
);
}
}
),
),
);
@ -65,6 +92,33 @@ class _IntroPageState extends State<IntroPage> {
);
}
Widget _text(BuildContext context) {
return PositionedDirectional(
bottom: 130,
child: Column(
spacing: MySpaces.s6,
children: [
Text(
context.translate.please_wait,
style: Marhey.medium22.copyWith(
color: MyColors.white,
),
),
StreamBuilder<DownloadEntity>(
initialData: DownloadEntity(),
stream: context.read<IntroBloc>().loadingStream,
builder: (context, snapshot) => Text(
'${context.translate.downloading_data} (${snapshot.data?.count.toMB ?? 0.0}mb / ${snapshot.data?.total.toMB ?? 0.0}mb)',
style: Marhey.medium12.copyWith(
color: MyColors.white,
),
),
),
],
),
);
}
Positioned _loading(BuildContext context) {
return Positioned(
bottom: MediaQuery.viewPaddingOf(context).bottom + MySpaces.s16,

11
lib/features/intro/presentation/ui/widgets/intro_loading_widget.dart

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_spaces.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart';
import 'package:hadi_hoda_flutter/features/intro/domain/entities/download_entity.dart';
class IntroLoadingWidget extends StatelessWidget {
@ -9,7 +10,7 @@ class IntroLoadingWidget extends StatelessWidget {
this.loadingStream,
});
final Stream<double>? loadingStream;
final Stream<DownloadEntity>? loadingStream;
@override
Widget build(BuildContext context) {
@ -32,8 +33,8 @@ class IntroLoadingWidget extends StatelessWidget {
],
),
),
child: StreamBuilder<double>(
initialData: 0,
child: StreamBuilder<DownloadEntity>(
initialData: DownloadEntity(),
stream: loadingStream,
builder: (context, snapshot) {
return Row(
@ -45,7 +46,7 @@ class IntroLoadingWidget extends StatelessWidget {
child: AnimatedContainer(
duration: const Duration(milliseconds: 300),
padding: EdgeInsetsDirectional.only(
end: 260 - ((snapshot.data ?? 0) * 260 / 100),
end: 260 - ((snapshot.data?.percent ?? 0) * 260 / 100),
),
decoration: BoxDecoration(
color: Color(0xFF1F59BD).withValues(alpha: 0.25),
@ -71,7 +72,7 @@ class IntroLoadingWidget extends StatelessWidget {
flex: 15,
child: Center(
child: Text(
'${snapshot.data?.toInt() ?? 0}%',
'${snapshot.data?.percent?.toInt() ?? 0}%',
style: DinoKids.regular17.copyWith(
color: Color(0XFF6E83A8),
),

46
lib/features/language/data/datasource/language_datasource.dart

@ -1,46 +0,0 @@
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<void> saveLevels({required LanguageParams params});
}
class LanguageDatasourceImpl implements ILanguageDatasource {
final IHttpRequest httpRequest;
const LanguageDatasourceImpl(this.httpRequest);
@override
Future<void> saveLevels({required LanguageParams params}) async {
await LocalStorage.saveData(
key: MyConstants.selectLanguage,
value: params.code ?? 'fa',
);
final Box<TotalDataEntity> 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<LevelEntity> levels = BaseResponse.getDataList<LevelEntity>(
response?['result'],
(json) => LevelModel.fromJson(json),
);
await data.add(TotalDataEntity(code: params.code, levels: levels));
}
}
}

29
lib/features/language/data/repository_impl/language_repository_impl.dart

@ -1,29 +0,0 @@
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<DataState<NoParams, MyException>> 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'));
}
}
}
}

8
lib/features/language/domain/repository/language_repository.dart

@ -1,8 +0,0 @@
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';
abstract class ILanguageRepository {
Future<DataState<NoParams, MyException>> saveLevels({required LanguageParams params});
}

17
lib/features/language/domain/usecases/save_levels_usecase.dart

@ -1,17 +0,0 @@
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/repository/language_repository.dart';
class SaveLevelsUseCase implements UseCase<NoParams, LanguageParams> {
final ILanguageRepository repository;
const SaveLevelsUseCase(this.repository);
@override
Future<DataState<NoParams, MyException>> call(LanguageParams params) {
return repository.saveLevels(params: params);
}
}

50
lib/features/language/presentation/bloc/language_bloc.dart

@ -1,26 +1,26 @@
import 'dart:async';
import 'dart:io';
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/constants/my_constants.dart';
import 'package:hadi_hoda_flutter/core/routers/my_routes.dart';
import 'package:hadi_hoda_flutter/core/status/base_status.dart';
import 'package:hadi_hoda_flutter/core/utils/context_provider.dart';
import 'package:hadi_hoda_flutter/core/utils/local_storage.dart';
import 'package:hadi_hoda_flutter/core/utils/storage_path.dart';
import 'package:hadi_hoda_flutter/features/language/domain/entity/language_entity.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<LanguageEvent, LanguageState> {
/// ------------constructor------------
LanguageBloc(
this._saveLevelsUseCase,
) : super(const LanguageState()) {
LanguageBloc() : super(const LanguageState()) {
LocalStorage.saveData(key: MyConstants.firstLanguagePage, value: 'true');
on<ChangeLanguageEvent>(_changeLanguageEvent);
on<SaveLevelsEvent>(_saveLevelsEvent);
on<InitLanguageEvent>(_initLanguageEvent);
}
/// ------------UseCases------------
final SaveLevelsUseCase _saveLevelsUseCase;
/// ------------Variables------------
final List<LanguageEntity> languages = [
@ -44,17 +44,31 @@ class LanguageBloc extends Bloc<LanguageEvent, LanguageState> {
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()));
},
),
await LocalStorage.saveData(
key: MyConstants.selectLanguage,
value: state.selectedLang.code ?? 'fa',
);
if (Directory(
'${StoragePath.documentDir.path}/${state.selectedLang.code}/files')
.existsSync()) {
if (ContextProvider.context.mounted) {
ContextProvider.context.goNamed(Routes.homePage);
}
} else {
await Future.wait([
LocalStorage.deleteData(key: MyConstants.downloadCompleted),
LocalStorage.deleteData(key: MyConstants.extractCompleted),
]);
if (ContextProvider.context.mounted) {
ContextProvider.context.goNamed(Routes.introPage);
}
}
}
FutureOr<void> _initLanguageEvent(InitLanguageEvent event, Emitter<LanguageState> emit) {
final String selectedLanguage = LocalStorage.readData(key: MyConstants.selectLanguage).isEmpty
? 'fa'
: LocalStorage.readData(key: MyConstants.selectLanguage);
emit(state.copyWith(selectedLang: LanguageEntity(code: selectedLanguage)));
}
}

5
lib/features/language/presentation/bloc/language_event.dart

@ -3,14 +3,15 @@ import 'package:hadi_hoda_flutter/features/language/domain/entity/language_entit
sealed class LanguageEvent {
const LanguageEvent();
}
class ChangeLanguageEvent extends LanguageEvent {
final LanguageEntity lang;
const ChangeLanguageEvent(this.lang);
}
class SaveLevelsEvent extends LanguageEvent {
const SaveLevelsEvent();
}
class InitLanguageEvent extends LanguageEvent {
const InitLanguageEvent();
}

24
lib/features/language/presentation/ui/language_page.dart

@ -1,11 +1,9 @@
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_colors.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_spaces.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart';
import 'package:hadi_hoda_flutter/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';
@ -71,7 +69,7 @@ class LanguagePage extends StatelessWidget {
Expanded _list(BuildContext context) {
return Expanded(
child: Material(
color: context.noColor,
color: MyColors.transparent,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(
@ -90,7 +88,7 @@ class LanguagePage extends StatelessWidget {
},
title: Text(context.read<LanguageBloc>().languages[index].title ?? ''),
titleTextStyle: Marhey.medium16.copyWith(
color: context.primaryColor,
color: MyColors.white,
),
contentPadding: EdgeInsets.symmetric(
vertical: MySpaces.s12,
@ -100,18 +98,6 @@ class LanguagePage extends StatelessWidget {
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,
@ -137,8 +123,8 @@ class LanguagePage extends StatelessWidget {
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12)),
),
selectedTileColor: context.primaryColor.withValues(alpha: 0.2),
selectedColor: context.primaryColor,
selectedTileColor: MyColors.white.withValues(alpha: 0.2),
selectedColor: MyColors.white,
);
}
),

4
lib/features/level/presentation/ui/widgets/level_widget.dart

@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_colors.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart';
import 'package:hadi_hoda_flutter/common_ui/theme/my_theme.dart';
import 'package:hadi_hoda_flutter/core/utils/my_image.dart';
import 'package:hadi_hoda_flutter/features/level/domain/entity/level_entity.dart';
@ -43,7 +43,7 @@ class LevelWidget extends StatelessWidget {
Text(
'$index',
style: DinoKids.regular26.copyWith(
color: context.primaryColor,
color: MyColors.white,
shadows: [
Shadow(
color: Color(0XFF5B5B5B),

8
lib/features/question/presentation/ui/question_page.dart

@ -1,9 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_colors.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_spaces.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart';
import 'package:hadi_hoda_flutter/common_ui/theme/my_theme.dart';
import 'package:hadi_hoda_flutter/core/utils/gap.dart';
import 'package:hadi_hoda_flutter/core/utils/my_image.dart';
import 'package:hadi_hoda_flutter/core/utils/my_localization.dart';
@ -82,7 +82,7 @@ class QuestionPage extends StatelessWidget {
builder: (context, state) => Text(
state.levelEntity?.title ?? '',
style: Marhey.bold14.copyWith(
color: context.primaryColor,
color: MyColors.white,
),
),
),
@ -109,7 +109,7 @@ class QuestionPage extends StatelessWidget {
builder: (context, state) => Text(
'Question ${state.currentStep} / ${state.levelEntity?.questions?.length ?? 0}',
style: Marhey.medium12.copyWith(
color: context.primaryColor.withValues(alpha: 0.5),
color: MyColors.white.withValues(alpha: 0.5),
shadows: [
Shadow(
offset: Offset(0, 1),
@ -125,7 +125,7 @@ class QuestionPage extends StatelessWidget {
state.levelEntity?.questions?[state.currentStep].title ?? '',
textAlign: TextAlign.center,
style: Marhey.medium12.copyWith(
color: context.primaryColor,
color: MyColors.white,
shadows: [
Shadow(
offset: Offset(0, 1),

4
lib/features/question/presentation/ui/widgets/refresh_button.dart

@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import 'package:hadi_hoda_flutter/common_ui/theme/my_theme.dart';
import 'package:hadi_hoda_flutter/common_ui/resources/my_colors.dart';
class RefreshButton extends StatelessWidget {
const RefreshButton({super.key, this.onTap,});
@ -9,7 +9,7 @@ class RefreshButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Material(
color: context.noColor,
color: MyColors.transparent,
child: Ink(
height: 48,
width: 48,

9
lib/init_bindings.dart

@ -12,10 +12,7 @@ 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/save_levels_usecase.dart';
import 'package:hadi_hoda_flutter/features/intro/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';
@ -52,12 +49,10 @@ void initBindings() {
locator.registerLazySingleton<IIntroDatasource>(() => IntroDatasourceImpl(locator()));
locator.registerLazySingleton<IIntroRepository>(() => IntroRepositoryImpl(locator()));
locator.registerLazySingleton<GetFilesUseCase>(() => GetFilesUseCase(locator()));
locator.registerLazySingleton<SaveLevelsUseCase>(() => SaveLevelsUseCase(locator()));
locator.registerLazySingleton<LoadingStreamUseCase>(() => LoadingStreamUseCase(locator()));
/// Language Feature
locator.registerLazySingleton<ILanguageDatasource>(() => LanguageDatasourceImpl(locator()));
locator.registerLazySingleton<ILanguageRepository>(() => LanguageRepositoryImpl(locator()));
locator.registerLazySingleton<SaveLevelsUseCase>(() => SaveLevelsUseCase(locator()));
/// Home Feature
locator.registerLazySingleton<IHomeDatasource>(() => HomeDatasourceImpl(locator()));

7
lib/l10n/app_en.arb

@ -3,5 +3,10 @@
"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.",
"select_language": "Select language",
"select": "Select"
"select": "Select",
"please_wait": "Please wait a few moments...",
"downloading_data": "Downloading initial data",
"lost_connection": "Lost connection!",
"try_again": "Try Again",
"connected_to_internet": "You must be connected to the internet to download the initial game data."
}

30
lib/l10n/app_localizations.dart

@ -123,6 +123,36 @@ abstract class AppLocalizations {
/// In en, this message translates to:
/// **'Select'**
String get select;
/// No description provided for @please_wait.
///
/// In en, this message translates to:
/// **'Please wait a few moments...'**
String get please_wait;
/// No description provided for @downloading_data.
///
/// In en, this message translates to:
/// **'Downloading initial data'**
String get downloading_data;
/// No description provided for @lost_connection.
///
/// In en, this message translates to:
/// **'Lost connection!'**
String get lost_connection;
/// No description provided for @try_again.
///
/// In en, this message translates to:
/// **'Try Again'**
String get try_again;
/// No description provided for @connected_to_internet.
///
/// In en, this message translates to:
/// **'You must be connected to the internet to download the initial game data.'**
String get connected_to_internet;
}
class _AppLocalizationsDelegate

16
lib/l10n/app_localizations_en.dart

@ -23,4 +23,20 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get select => 'Select';
@override
String get please_wait => 'Please wait a few moments...';
@override
String get downloading_data => 'Downloading initial data';
@override
String get lost_connection => 'Lost connection!';
@override
String get try_again => 'Try Again';
@override
String get connected_to_internet =>
'You must be connected to the internet to download the initial game data.';
}
Loading…
Cancel
Save