added lang

This commit is contained in:
komekh 2024-08-03 12:58:07 +05:00
parent 20e4b6654e
commit 8088935aef
21 changed files with 287 additions and 38 deletions

3
assets/locale/ru-RU.json Normal file
View File

@ -0,0 +1,3 @@
{
"profile_select_lang": "Выберите язык"
}

3
assets/locale/tr-TR.json Normal file
View File

@ -0,0 +1,3 @@
{
"profile_select_lang": "Dil saýlamak"
}

View File

@ -1,2 +1,3 @@
export 'bottom_navbar_cubit/bottom_navbar_cubit.dart';
export 'user_bloc/user_bloc.dart';
export 'language_bloc/language_bloc.dart';

View File

@ -0,0 +1,52 @@
import 'dart:async';
import 'package:easy_localization/easy_localization.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../core/core.dart';
import '../../data/data.dart';
part 'language_event.dart';
part 'language_state.dart';
const kDefaultLocale = Locale('ru');
class LanguageBloc extends Bloc<LanguageEvent, LanguageState> {
LanguageBloc() : super(const LanguageState()) {
on<LanguageInitial>(_onLanguageInitial);
on<LanguageChanged>(_onLanguageChanged);
}
FutureOr<void> _onLanguageChanged(LanguageChanged event, Emitter<LanguageState> emit) async {
final ctx = event.context;
if (!ctx.mounted) return;
final lang = event.lang;
final locale = Locale(lang.code, lang.countryCode);
await ctx.setLocale(locale);
emit(state.copyWith(locale: locale));
/// Keep in shared preference
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString(activeLang, lang.code);
}
FutureOr<void> _onLanguageInitial(LanguageInitial event, Emitter<LanguageState> emit) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
final langCode = prefs.getString(activeLang) ?? 'tr';
final lang = languages.where((l) => l.code == langCode).first;
emit(
state.copyWith(
locale: Locale(lang.code, lang.countryCode),
),
);
}
}

View File

@ -0,0 +1,20 @@
part of 'language_bloc.dart';
sealed class LanguageEvent extends Equatable {
const LanguageEvent();
@override
List<Object> get props => [];
}
final class LanguageInitial extends LanguageEvent {}
final class LanguageChanged extends LanguageEvent {
final Language lang;
final BuildContext context;
const LanguageChanged({required this.lang, required this.context});
@override
List<Object> get props => [lang, context];
}

View File

@ -0,0 +1,19 @@
part of 'language_bloc.dart';
class LanguageState extends Equatable {
final Locale locale;
const LanguageState({
this.locale = const Locale('tr', 'TR'),
});
@override
List<Object?> get props => [locale];
LanguageState copyWith({
Locale? locale,
}) {
return LanguageState(
locale: locale ?? this.locale,
);
}
}

View File

@ -1,3 +1,4 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@ -13,6 +14,9 @@ class MyApp extends StatelessWidget {
return MultiBlocProvider(
providers: [
BlocProvider(create: (context) => di.sl<NavigationCubit>()),
BlocProvider(
create: (context) => di.sl<LanguageBloc>()..add(LanguageInitial()),
),
BlocProvider(
create: (context) => di.sl<UserBloc>(), //..add(CheckUser()),
),
@ -22,6 +26,9 @@ class MyApp extends StatelessWidget {
title: appTitle,
onGenerateRoute: AppRouter.onGenerateRoute,
onGenerateInitialRoutes: (initialRoute) => AppRouter.generateInitialRoutes(initialRoute),
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
initialRoute: AppRouter.root,
),
);

View File

@ -4,3 +4,6 @@ const String appTitle = 'Cargo App';
// Storage and Databases
const String articlesTableName = '';
const String databaseName = '';
// SharedPreferences
const String activeLang = 'activeLang';

View File

@ -0,0 +1,6 @@
import '../../data.dart';
List<Language> languages = [
Language(id: 1, language: 'Türkmen dili', code: 'tr', countryCode: 'TR'),
Language(id: 2, language: 'Русский', code: 'ru', countryCode: 'RU'),
];

View File

@ -1 +1,2 @@
export 'user_local_data_source.dart';
export 'languages_data_source.dart';

View File

@ -0,0 +1,12 @@
class Language {
Language({
required this.id,
required this.language,
required this.code,
required this.countryCode,
});
int id;
String language;
String code;
String countryCode;
}

View File

@ -1,2 +1,3 @@
export 'user/user_model.dart';
export 'language.dart';
export 'user/authentication_response_model.dart';
export 'user/user_model.dart';

View File

@ -2,6 +2,7 @@ import 'package:get_it/get_it.dart';
import 'common.dart';
import 'cubits.dart';
import 'language.dart';
import 'user.dart';
final sl = GetIt.instance;
@ -10,6 +11,7 @@ final sl = GetIt.instance;
Future<void> init() async {
// Register features
registerUserFeature();
registerLanguageFeature();
// registerCategoryFeature();
// registerProductFeature();
// registerDeliveryInfoFeature();

7
lib/di/language.dart Normal file
View File

@ -0,0 +1,7 @@
import '../application/language_bloc/language_bloc.dart';
import 'di.dart';
void registerLanguageFeature() {
// Product BLoC and Use Cases
sl.registerFactory(() => LanguageBloc());
}

View File

@ -1,3 +1,4 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@ -8,6 +9,7 @@ import 'di/di.dart' as di;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
// await GetStorage.init();
@ -25,13 +27,24 @@ Future<void> main() async {
statusBarBrightness: Brightness.dark,
));
runApp(Phoenix(child: const MyApp()));
runApp(
EasyLocalization(
supportedLocales: const [
Locale('tr', 'TR'),
Locale('ru', 'RU'),
],
path: 'assets/locale',
fallbackLocale: const Locale('tr', 'TR'),
startLocale: const Locale('tr', 'TR'),
child: Phoenix(child: const MyApp()),
),
);
}
/// ADDING PROGRESS
// 1 create bloc
// 2 create use_case under domain folder
// 3 create repository
// 4 create repository implementation
// 5 create data source
// 6 add di register
// 6 add di register

View File

@ -1,8 +1,8 @@
import 'package:cargo/presentation/presentation.dart';
import 'package:flutter/material.dart';
import '../../configs/configs.dart';
import '../../core/core.dart';
import '../widgets/widgets.dart';
class OrdersScreen extends StatelessWidget {
const OrdersScreen({super.key});

View File

@ -1,7 +1,6 @@
import 'package:cargo/configs/app_typography.dart';
import 'package:cargo/configs/space.dart';
import 'package:cargo/presentation/presentation.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import '../../configs/configs.dart';
import '../../core/core.dart';
@ -103,16 +102,19 @@ class ProfileScreen extends StatelessWidget {
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
/// identity
const RowWidget(
text: 'Dil saýlamak (Türkmen dili)',
leadingIcon: Icons.language_outlined,
trailingIcon: Icons.arrow_forward_ios,
/// language
GestureDetector(
onTap: () => onSelectLang(context),
child: Container(
color: Colors.transparent,
child: RowWidget(
text: 'profile_select_lang'.tr(),
leadingIcon: Icons.language_outlined,
trailingIcon: Icons.arrow_forward_ios,
),
),
),
/// gap
Space.yf(1),
/// name surname
const RowWidget(
text: 'Gizlinlik syýasaty',
@ -120,9 +122,6 @@ class ProfileScreen extends StatelessWidget {
trailingIcon: Icons.arrow_forward_ios,
),
/// gap
Space.yf(1),
/// phone
const RowWidget(
text: 'Ulanyş şertleri',
@ -175,28 +174,31 @@ class RowWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Row(
children: [
Icon(
leadingIcon,
color: AppColors.darkGrey,
),
Space.x!,
Text(
text,
style: AppText.b1!.copyWith(
color: AppColors.darkGrey,
),
),
if (trailingIcon != null) ...[
const Spacer(),
return Padding(
padding: Space.vf(0.5),
child: Row(
children: [
Icon(
trailingIcon,
leadingIcon,
color: AppColors.darkGrey,
size: AppDimensions.normalize(7),
),
]
],
Space.x!,
Text(
text,
style: AppText.b1!.copyWith(
color: AppColors.darkGrey,
),
),
if (trailingIcon != null) ...[
const Spacer(),
Icon(
trailingIcon,
color: AppColors.darkGrey,
size: AppDimensions.normalize(7),
),
]
],
),
);
}
}

View File

@ -0,0 +1,73 @@
import 'package:cargo/configs/configs.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../application/application.dart';
import '../../data/data_sources/local/languages_data_source.dart';
class BottomSheetContent extends StatelessWidget {
const BottomSheetContent({super.key});
@override
Widget build(BuildContext context) {
return SizedBox(
height: AppDimensions.normalize(65),
child: BlocBuilder<LanguageBloc, LanguageState>(
builder: (context, state) {
return Container(
padding: Space.vf(),
child: ListView.separated(
itemCount: languages.length,
separatorBuilder: (context, index) => Padding(
padding: Space.hf(1),
child: const Divider(),
),
itemBuilder: (context, index) {
final lang = languages[index];
return ListTile(
title: Text(
lang.language,
style: AppText.b1,
),
trailing: state.locale.languageCode == lang.code
? Icon(
Icons.check,
color: Colors.green,
size: 26.0,
shadows: [
Shadow(
offset: const Offset(0, 2),
blurRadius: 3.0,
color: Colors.black.withOpacity(0.3),
),
],
)
: null,
onTap: () {
debugPrint('lang_selection');
context.read<LanguageBloc>().add(
LanguageChanged(
lang: lang,
context: context,
),
);
Navigator.of(context).pop();
},
);
},
),
);
},
),
);
}
}
Future<void> onSelectLang(BuildContext context) async {
await showModalBottomSheet(
context: context,
builder: (context) {
return const BottomSheetContent();
},
);
}

View File

@ -9,3 +9,4 @@ export 'order_header.dart';
export 'successful_auth_dialog.dart';
export 'vertical_line.dart';
export 'dashed_line.dart';
export 'lang_selection.dart';

View File

@ -81,6 +81,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.10.1"
easy_localization:
dependency: "direct main"
description:
name: easy_localization
sha256: fa59bcdbbb911a764aa6acf96bbb6fa7a5cf8234354fc45ec1a43a0349ef0201
url: "https://pub.dev"
source: hosted
version: "3.0.7"
easy_logger:
dependency: transitive
description:
name: easy_logger
sha256: c764a6e024846f33405a2342caf91c62e357c24b02c04dbc712ef232bf30ffb7
url: "https://pub.dev"
source: hosted
version: "0.0.2"
equatable:
dependency: "direct main"
description:
@ -134,6 +150,11 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.2"
flutter_localizations:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
flutter_map:
dependency: "direct main"
description:

View File

@ -26,6 +26,7 @@ dependencies:
flutter_map: ">=6.0.0 <7.0.0"
latlong2: ^0.9.0
flutter_map_marker_cluster: ^1.3.6
easy_localization: ^3.0.7
dev_dependencies:
flutter_test:
@ -40,6 +41,7 @@ flutter:
- assets/svg/
- assets/svg/logo/
- assets/images/
- assets/locale/
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware