Adds localization support with English and Russian
Initializes internationalization (i18n) for the application. Introduces `AppLocalizations` to manage localized strings, along with English and Russian translations. Configures Flutter to use the localization delegates and supported locales. This allows the app to display text in the user's preferred language.
This commit is contained in:
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"dart.flutterSdkPath": "C:\\Sanders\\Flutter\\flutter_windows_3.32.2-stable\\flutter"
|
||||
}
|
||||
@@ -0,0 +1,344 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:intl/intl.dart' as intl;
|
||||
|
||||
import 'app_localizations_en.dart';
|
||||
import 'app_localizations_ru.dart';
|
||||
|
||||
// ignore_for_file: type=lint
|
||||
|
||||
/// Callers can lookup localized strings with an instance of AppLocalizations
|
||||
/// returned by `AppLocalizations.of(context)`.
|
||||
///
|
||||
/// Applications need to include `AppLocalizations.delegate()` in their app's
|
||||
/// `localizationDelegates` list, and the locales they support in the app's
|
||||
/// `supportedLocales` list. For example:
|
||||
///
|
||||
/// ```dart
|
||||
/// import 'l10n/app_localizations.dart';
|
||||
///
|
||||
/// return MaterialApp(
|
||||
/// localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
/// supportedLocales: AppLocalizations.supportedLocales,
|
||||
/// home: MyApplicationHome(),
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// ## Update pubspec.yaml
|
||||
///
|
||||
/// Please make sure to update your pubspec.yaml to include the following
|
||||
/// packages:
|
||||
///
|
||||
/// ```yaml
|
||||
/// dependencies:
|
||||
/// # Internationalization support.
|
||||
/// flutter_localizations:
|
||||
/// sdk: flutter
|
||||
/// intl: any # Use the pinned version from flutter_localizations
|
||||
///
|
||||
/// # Rest of dependencies
|
||||
/// ```
|
||||
///
|
||||
/// ## iOS Applications
|
||||
///
|
||||
/// iOS applications define key application metadata, including supported
|
||||
/// locales, in an Info.plist file that is built into the application bundle.
|
||||
/// To configure the locales supported by your app, you’ll need to edit this
|
||||
/// file.
|
||||
///
|
||||
/// First, open your project’s ios/Runner.xcworkspace Xcode workspace file.
|
||||
/// Then, in the Project Navigator, open the Info.plist file under the Runner
|
||||
/// project’s Runner folder.
|
||||
///
|
||||
/// Next, select the Information Property List item, select Add Item from the
|
||||
/// Editor menu, then select Localizations from the pop-up menu.
|
||||
///
|
||||
/// Select and expand the newly-created Localizations item then, for each
|
||||
/// locale your application supports, add a new item and select the locale
|
||||
/// you wish to add from the pop-up menu in the Value field. This list should
|
||||
/// be consistent with the languages listed in the AppLocalizations.supportedLocales
|
||||
/// property.
|
||||
abstract class AppLocalizations {
|
||||
AppLocalizations(String locale)
|
||||
: localeName = intl.Intl.canonicalizedLocale(locale.toString());
|
||||
|
||||
final String localeName;
|
||||
|
||||
static AppLocalizations? of(BuildContext context) {
|
||||
return Localizations.of<AppLocalizations>(context, AppLocalizations);
|
||||
}
|
||||
|
||||
static const LocalizationsDelegate<AppLocalizations> delegate =
|
||||
_AppLocalizationsDelegate();
|
||||
|
||||
/// A list of this localizations delegate along with the default localizations
|
||||
/// delegates.
|
||||
///
|
||||
/// Returns a list of localizations delegates containing this delegate along with
|
||||
/// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate,
|
||||
/// and GlobalWidgetsLocalizations.delegate.
|
||||
///
|
||||
/// Additional delegates can be added by appending to this list in
|
||||
/// MaterialApp. This list does not have to be used at all if a custom list
|
||||
/// of delegates is preferred or required.
|
||||
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates =
|
||||
<LocalizationsDelegate<dynamic>>[
|
||||
delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
];
|
||||
|
||||
/// A list of this localizations delegate's supported locales.
|
||||
static const List<Locale> supportedLocales = <Locale>[
|
||||
Locale('en'),
|
||||
Locale('ru'),
|
||||
];
|
||||
|
||||
/// No description provided for @appTitle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Budget App'**
|
||||
String get appTitle;
|
||||
|
||||
/// No description provided for @homePageTitle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Home'**
|
||||
String get homePageTitle;
|
||||
|
||||
/// No description provided for @reportsPageTitle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Reports'**
|
||||
String get reportsPageTitle;
|
||||
|
||||
/// No description provided for @settingsPageTitle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Settings'**
|
||||
String get settingsPageTitle;
|
||||
|
||||
/// No description provided for @addTransactionButton.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Add new transaction'**
|
||||
String get addTransactionButton;
|
||||
|
||||
/// No description provided for @noTransactionsText.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'No transactions yet'**
|
||||
String get noTransactionsText;
|
||||
|
||||
/// No description provided for @loadingTransactionsText.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Loading transactions...'**
|
||||
String get loadingTransactionsText;
|
||||
|
||||
/// No description provided for @transactionErrorText.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Error: {message}'**
|
||||
String transactionErrorText(Object message);
|
||||
|
||||
/// No description provided for @loginPageTitle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Login'**
|
||||
String get loginPageTitle;
|
||||
|
||||
/// No description provided for @nameFieldLabel.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Name'**
|
||||
String get nameFieldLabel;
|
||||
|
||||
/// No description provided for @emailFieldLabel.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Email'**
|
||||
String get emailFieldLabel;
|
||||
|
||||
/// No description provided for @nameFieldEmptyError.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Please enter your name'**
|
||||
String get nameFieldEmptyError;
|
||||
|
||||
/// No description provided for @emailFieldEmptyError.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Please enter your email'**
|
||||
String get emailFieldEmptyError;
|
||||
|
||||
/// No description provided for @loginButtonText.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Login / Register'**
|
||||
String get loginButtonText;
|
||||
|
||||
/// No description provided for @darkModeSetting.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Dark Theme'**
|
||||
String get darkModeSetting;
|
||||
|
||||
/// No description provided for @darkModeDescription.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Toggle between light and dark theme'**
|
||||
String get darkModeDescription;
|
||||
|
||||
/// No description provided for @languageSetting.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Language'**
|
||||
String get languageSetting;
|
||||
|
||||
/// No description provided for @languageDescription.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Change application language'**
|
||||
String get languageDescription;
|
||||
|
||||
/// No description provided for @russianLanguage.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Russian'**
|
||||
String get russianLanguage;
|
||||
|
||||
/// No description provided for @englishLanguage.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'English'**
|
||||
String get englishLanguage;
|
||||
|
||||
/// No description provided for @defaultUser.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Default User'**
|
||||
String get defaultUser;
|
||||
|
||||
/// No description provided for @currencySetting.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Default Currency'**
|
||||
String get currencySetting;
|
||||
|
||||
/// No description provided for @currencyDescription.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Set the default currency for transactions'**
|
||||
String get currencyDescription;
|
||||
|
||||
/// No description provided for @transactionsHistoryTitle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Transactions History'**
|
||||
String get transactionsHistoryTitle;
|
||||
|
||||
/// No description provided for @balance.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Balance'**
|
||||
String get balance;
|
||||
|
||||
/// No description provided for @income.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Income'**
|
||||
String get income;
|
||||
|
||||
/// No description provided for @expense.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Expense'**
|
||||
String get expense;
|
||||
|
||||
/// No description provided for @amount.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Amount'**
|
||||
String get amount;
|
||||
|
||||
/// No description provided for @vendor.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Vendor'**
|
||||
String get vendor;
|
||||
|
||||
/// No description provided for @category.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Category'**
|
||||
String get category;
|
||||
|
||||
/// No description provided for @date.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Date'**
|
||||
String get date;
|
||||
|
||||
/// No description provided for @requiredField.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Required field'**
|
||||
String get requiredField;
|
||||
|
||||
/// No description provided for @invalidNumber.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Invalid number'**
|
||||
String get invalidNumber;
|
||||
|
||||
/// No description provided for @cancel.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Cancel'**
|
||||
String get cancel;
|
||||
|
||||
/// No description provided for @save.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Save'**
|
||||
String get save;
|
||||
}
|
||||
|
||||
class _AppLocalizationsDelegate
|
||||
extends LocalizationsDelegate<AppLocalizations> {
|
||||
const _AppLocalizationsDelegate();
|
||||
|
||||
@override
|
||||
Future<AppLocalizations> load(Locale locale) {
|
||||
return SynchronousFuture<AppLocalizations>(lookupAppLocalizations(locale));
|
||||
}
|
||||
|
||||
@override
|
||||
bool isSupported(Locale locale) =>
|
||||
<String>['en', 'ru'].contains(locale.languageCode);
|
||||
|
||||
@override
|
||||
bool shouldReload(_AppLocalizationsDelegate old) => false;
|
||||
}
|
||||
|
||||
AppLocalizations lookupAppLocalizations(Locale locale) {
|
||||
// Lookup logic when only language code is specified.
|
||||
switch (locale.languageCode) {
|
||||
case 'en':
|
||||
return AppLocalizationsEn();
|
||||
case 'ru':
|
||||
return AppLocalizationsRu();
|
||||
}
|
||||
|
||||
throw FlutterError(
|
||||
'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
|
||||
'an issue with the localizations generation tool. Please file an issue '
|
||||
'on GitHub with a reproducible sample app and the gen-l10n configuration '
|
||||
'that was used.',
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
// ignore: unused_import
|
||||
import 'package:intl/intl.dart' as intl;
|
||||
import 'app_localizations.dart';
|
||||
|
||||
// ignore_for_file: type=lint
|
||||
|
||||
/// The translations for English (`en`).
|
||||
class AppLocalizationsEn extends AppLocalizations {
|
||||
AppLocalizationsEn([String locale = 'en']) : super(locale);
|
||||
|
||||
@override
|
||||
String get appTitle => 'Budget App';
|
||||
|
||||
@override
|
||||
String get homePageTitle => 'Home';
|
||||
|
||||
@override
|
||||
String get reportsPageTitle => 'Reports';
|
||||
|
||||
@override
|
||||
String get settingsPageTitle => 'Settings';
|
||||
|
||||
@override
|
||||
String get addTransactionButton => 'Add new transaction';
|
||||
|
||||
@override
|
||||
String get noTransactionsText => 'No transactions yet';
|
||||
|
||||
@override
|
||||
String get loadingTransactionsText => 'Loading transactions...';
|
||||
|
||||
@override
|
||||
String transactionErrorText(Object message) {
|
||||
return 'Error: $message';
|
||||
}
|
||||
|
||||
@override
|
||||
String get loginPageTitle => 'Login';
|
||||
|
||||
@override
|
||||
String get nameFieldLabel => 'Name';
|
||||
|
||||
@override
|
||||
String get emailFieldLabel => 'Email';
|
||||
|
||||
@override
|
||||
String get nameFieldEmptyError => 'Please enter your name';
|
||||
|
||||
@override
|
||||
String get emailFieldEmptyError => 'Please enter your email';
|
||||
|
||||
@override
|
||||
String get loginButtonText => 'Login / Register';
|
||||
|
||||
@override
|
||||
String get darkModeSetting => 'Dark Theme';
|
||||
|
||||
@override
|
||||
String get darkModeDescription => 'Toggle between light and dark theme';
|
||||
|
||||
@override
|
||||
String get languageSetting => 'Language';
|
||||
|
||||
@override
|
||||
String get languageDescription => 'Change application language';
|
||||
|
||||
@override
|
||||
String get russianLanguage => 'Russian';
|
||||
|
||||
@override
|
||||
String get englishLanguage => 'English';
|
||||
|
||||
@override
|
||||
String get defaultUser => 'Default User';
|
||||
|
||||
@override
|
||||
String get currencySetting => 'Default Currency';
|
||||
|
||||
@override
|
||||
String get currencyDescription => 'Set the default currency for transactions';
|
||||
|
||||
@override
|
||||
String get transactionsHistoryTitle => 'Transactions History';
|
||||
|
||||
@override
|
||||
String get balance => 'Balance';
|
||||
|
||||
@override
|
||||
String get income => 'Income';
|
||||
|
||||
@override
|
||||
String get expense => 'Expense';
|
||||
|
||||
@override
|
||||
String get amount => 'Amount';
|
||||
|
||||
@override
|
||||
String get vendor => 'Vendor';
|
||||
|
||||
@override
|
||||
String get category => 'Category';
|
||||
|
||||
@override
|
||||
String get date => 'Date';
|
||||
|
||||
@override
|
||||
String get requiredField => 'Required field';
|
||||
|
||||
@override
|
||||
String get invalidNumber => 'Invalid number';
|
||||
|
||||
@override
|
||||
String get cancel => 'Cancel';
|
||||
|
||||
@override
|
||||
String get save => 'Save';
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
// ignore: unused_import
|
||||
import 'package:intl/intl.dart' as intl;
|
||||
import 'app_localizations.dart';
|
||||
|
||||
// ignore_for_file: type=lint
|
||||
|
||||
/// The translations for Russian (`ru`).
|
||||
class AppLocalizationsRu extends AppLocalizations {
|
||||
AppLocalizationsRu([String locale = 'ru']) : super(locale);
|
||||
|
||||
@override
|
||||
String get appTitle => 'Бюджетное приложение';
|
||||
|
||||
@override
|
||||
String get homePageTitle => 'Главная';
|
||||
|
||||
@override
|
||||
String get reportsPageTitle => 'Отчеты';
|
||||
|
||||
@override
|
||||
String get settingsPageTitle => 'Настройки';
|
||||
|
||||
@override
|
||||
String get addTransactionButton => 'Добавить новую транзакцию';
|
||||
|
||||
@override
|
||||
String get noTransactionsText => 'Нет транзакций';
|
||||
|
||||
@override
|
||||
String get loadingTransactionsText => 'Загрузка транзакций...';
|
||||
|
||||
@override
|
||||
String transactionErrorText(Object message) {
|
||||
return 'Ошибка: $message';
|
||||
}
|
||||
|
||||
@override
|
||||
String get loginPageTitle => 'Вход';
|
||||
|
||||
@override
|
||||
String get nameFieldLabel => 'Имя';
|
||||
|
||||
@override
|
||||
String get emailFieldLabel => 'Email';
|
||||
|
||||
@override
|
||||
String get nameFieldEmptyError => 'Пожалуйста, введите имя';
|
||||
|
||||
@override
|
||||
String get emailFieldEmptyError => 'Пожалуйста, введите email';
|
||||
|
||||
@override
|
||||
String get loginButtonText => 'Войти / Зарегистрироваться';
|
||||
|
||||
@override
|
||||
String get darkModeSetting => 'Темная тема';
|
||||
|
||||
@override
|
||||
String get darkModeDescription => 'Переключить между светлой и темной темой';
|
||||
|
||||
@override
|
||||
String get languageSetting => 'Язык';
|
||||
|
||||
@override
|
||||
String get languageDescription => 'Изменить язык приложения';
|
||||
|
||||
@override
|
||||
String get russianLanguage => 'Русский';
|
||||
|
||||
@override
|
||||
String get englishLanguage => 'Английский';
|
||||
|
||||
@override
|
||||
String get defaultUser => 'Пользователь по умолчанию';
|
||||
|
||||
@override
|
||||
String get currencySetting => 'Валюта по умолчанию';
|
||||
|
||||
@override
|
||||
String get currencyDescription =>
|
||||
'Установить валюту по умолчанию для транзакций';
|
||||
|
||||
@override
|
||||
String get transactionsHistoryTitle => 'История транзакций';
|
||||
|
||||
@override
|
||||
String get balance => 'Баланс';
|
||||
|
||||
@override
|
||||
String get income => 'Доходы';
|
||||
|
||||
@override
|
||||
String get expense => 'Расходы';
|
||||
|
||||
@override
|
||||
String get amount => 'Сумма';
|
||||
|
||||
@override
|
||||
String get vendor => 'Название';
|
||||
|
||||
@override
|
||||
String get category => 'Категория';
|
||||
|
||||
@override
|
||||
String get date => 'Дата';
|
||||
|
||||
@override
|
||||
String get requiredField => 'Обязательное поле';
|
||||
|
||||
@override
|
||||
String get invalidNumber => 'Неверный формат числа';
|
||||
|
||||
@override
|
||||
String get cancel => 'Отмена';
|
||||
|
||||
@override
|
||||
String get save => 'Сохранить';
|
||||
}
|
||||
+2
-2
@@ -9,6 +9,7 @@ import 'package:budget_app/pages/home/home_page.dart';
|
||||
import 'theme/app_theme.dart';
|
||||
import 'injection_container.dart' as di;
|
||||
import 'logic/settings/settings_cubit.dart'; // Импортируем SettingsCubit
|
||||
import 'logic/transaction/transaction_bloc.dart';
|
||||
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
@@ -30,6 +31,7 @@ class _MyAppState extends State<MyApp> {
|
||||
providers: [
|
||||
BlocProvider(create: (context) => GetIt.instance<AuthBloc>()..add(AuthStarted())),
|
||||
BlocProvider(create: (context) => GetIt.instance<SettingsCubit>()),
|
||||
BlocProvider(create: (context) => GetIt.instance<TransactionBloc>()),
|
||||
],
|
||||
child: BlocBuilder<SettingsCubit, SettingsState>(
|
||||
builder: (context, settingsState) {
|
||||
@@ -62,5 +64,3 @@ class _MyAppState extends State<MyApp> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user