diff --git a/client-mobile/android/app/build.gradle b/client-mobile/android/app/build.gradle index ce1ce77..74a7adb 100644 --- a/client-mobile/android/app/build.gradle +++ b/client-mobile/android/app/build.gradle @@ -24,7 +24,7 @@ if (flutterVersionName == null) { android { namespace "com.example.messenger_app" - compileSdkVersion 35 + compileSdkVersion 36 ndkVersion flutter.ndkVersion compileOptions { diff --git a/client-mobile/l10n.yaml b/client-mobile/l10n.yaml index 3a803ff..a2db93e 100644 --- a/client-mobile/l10n.yaml +++ b/client-mobile/l10n.yaml @@ -2,3 +2,5 @@ arb-dir: l10n template-arb-file: app_ru.arb output-localization-file: app_localizations.dart output-class: AppLocalizations +output-dir: lib/l10n +synthetic-package: false diff --git a/client-mobile/l10n/app_en.arb b/client-mobile/l10n/app_en.arb index ae47019..00a1f0d 100644 --- a/client-mobile/l10n/app_en.arb +++ b/client-mobile/l10n/app_en.arb @@ -5,7 +5,7 @@ "contacts": "Contacts", "settings": "Settings", "login": "Login", - "email": "Email", + "username": "Login", "password": "Password", "name": "Name", "loginButton": "Sign In", @@ -26,7 +26,7 @@ "import": "Import", "federation": "Federation", "domainUrl": "Domain", - "enableRegistration": "Registration Enabled", + "registrationStatus": "Registration", "enabled": "Enabled", "disabled": "Disabled", "language": "Language", @@ -47,5 +47,37 @@ "user": "User", "edit": "Edit", "serverConnectionError": "Server connection error", - "settingsSaved": "Settings saved" + "connected": "Connected", + "unknownError": "Unknown error", + "networkError": "Network error", + "serverError": "Server error", + "parsingError": "Data parsing error", + "voice": "Voice Calls", + "video": "Video Calls", + "lifetime": "Lifetime", + "groups": "Groups", + "maxParticipants": "Max participants", + "hours": "h", + "dailyLimit": "Daily Limit", + "historyLimit": "History Limit", + "maxFileSize": "Max File Size", + "noLimit": "No Limit", + "allowForwarding": "Forwarding", + "allowReactions": "Reactions", + "allowReplies": "Replies", + "allowQuoting": "Quoting", + "allowMessageDeletion": "Deletion", + "forbidCopying": "Forbid Copying", + "allowLinks": "Links", + "allowPolls": "Polls", + "allowPinning": "Pins", + "allowMedia": "Media", + "description": "Description", + "server": "Server", + "notSpecified": "not specified", + "settingsSaved": "Settings saved", + "enterUsername": "Enter login", + "invalidUsername": "Login must be at least 3 characters and without Cyrillic", + "loginFailed": "Login failed. Check your login and password", + "registrationFailed": "Registration failed" } diff --git a/client-mobile/l10n/app_localizations.dart b/client-mobile/l10n/app_localizations.dart deleted file mode 100644 index 044ad11..0000000 --- a/client-mobile/l10n/app_localizations.dart +++ /dev/null @@ -1,421 +0,0 @@ -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(context, AppLocalizations); - } - - static const LocalizationsDelegate 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> localizationsDelegates = - >[ - delegate, - GlobalMaterialLocalizations.delegate, - GlobalCupertinoLocalizations.delegate, - GlobalWidgetsLocalizations.delegate, - ]; - - /// A list of this localizations delegate's supported locales. - static const List supportedLocales = [ - Locale('en'), - Locale('ru') - ]; - - /// No description provided for @appTitle. - /// - /// In ru, this message translates to: - /// **'Мессенджер'** - String get appTitle; - - /// No description provided for @chats. - /// - /// In ru, this message translates to: - /// **'Чаты'** - String get chats; - - /// No description provided for @contacts. - /// - /// In ru, this message translates to: - /// **'Контакты'** - String get contacts; - - /// No description provided for @settings. - /// - /// In ru, this message translates to: - /// **'Настройки'** - String get settings; - - /// No description provided for @login. - /// - /// In ru, this message translates to: - /// **'Вход'** - String get login; - - /// No description provided for @email. - /// - /// In ru, this message translates to: - /// **'Email'** - String get email; - - /// No description provided for @password. - /// - /// In ru, this message translates to: - /// **'Пароль'** - String get password; - - /// No description provided for @name. - /// - /// In ru, this message translates to: - /// **'Имя'** - String get name; - - /// No description provided for @loginButton. - /// - /// In ru, this message translates to: - /// **'Войти'** - String get loginButton; - - /// No description provided for @register. - /// - /// In ru, this message translates to: - /// **'Зарегистрироваться'** - String get register; - - /// No description provided for @noAccount. - /// - /// In ru, this message translates to: - /// **'Нет аккаунта? Зарегистрироваться'** - String get noAccount; - - /// No description provided for @logout. - /// - /// In ru, this message translates to: - /// **'Выйти из аккаунта'** - String get logout; - - /// No description provided for @serverSettings. - /// - /// In ru, this message translates to: - /// **'Настройки сервера'** - String get serverSettings; - - /// No description provided for @apiUrl. - /// - /// In ru, this message translates to: - /// **'Адрес API'** - String get apiUrl; - - /// No description provided for @apiUrlHint. - /// - /// In ru, this message translates to: - /// **'https://api.example.com'** - String get apiUrlHint; - - /// No description provided for @save. - /// - /// In ru, this message translates to: - /// **'Сохранить'** - String get save; - - /// No description provided for @serverConfig. - /// - /// In ru, this message translates to: - /// **'Конфигурация сервера'** - String get serverConfig; - - /// No description provided for @system. - /// - /// In ru, this message translates to: - /// **'Система'** - String get system; - - /// No description provided for @stories. - /// - /// In ru, this message translates to: - /// **'Истории'** - String get stories; - - /// No description provided for @chatsModule. - /// - /// In ru, this message translates to: - /// **'Чаты'** - String get chatsModule; - - /// No description provided for @messages. - /// - /// In ru, this message translates to: - /// **'Сообщения'** - String get messages; - - /// No description provided for @calls. - /// - /// In ru, this message translates to: - /// **'Звонки'** - String get calls; - - /// No description provided for @klipy. - /// - /// In ru, this message translates to: - /// **'Клипы'** - String get klipy; - - /// No description provided for @import. - /// - /// In ru, this message translates to: - /// **'Импорт'** - String get import; - - /// No description provided for @federation. - /// - /// In ru, this message translates to: - /// **'Федерация'** - String get federation; - - /// No description provided for @domainUrl. - /// - /// In ru, this message translates to: - /// **'Домен'** - String get domainUrl; - - /// No description provided for @enableRegistration. - /// - /// In ru, this message translates to: - /// **'Регистрация включена'** - String get enableRegistration; - - /// No description provided for @enabled. - /// - /// In ru, this message translates to: - /// **'Включено'** - String get enabled; - - /// No description provided for @disabled. - /// - /// In ru, this message translates to: - /// **'Отключено'** - String get disabled; - - /// No description provided for @language. - /// - /// In ru, this message translates to: - /// **'Язык'** - String get language; - - /// No description provided for @russian. - /// - /// In ru, this message translates to: - /// **'Русский'** - String get russian; - - /// No description provided for @english. - /// - /// In ru, this message translates to: - /// **'English'** - String get english; - - /// No description provided for @notifications. - /// - /// In ru, this message translates to: - /// **'Уведомления'** - String get notifications; - - /// No description provided for @privacy. - /// - /// In ru, this message translates to: - /// **'Конфиденциальность'** - String get privacy; - - /// No description provided for @soundsAndVibration. - /// - /// In ru, this message translates to: - /// **'Звуки и вибрация'** - String get soundsAndVibration; - - /// No description provided for @dataAndStorage. - /// - /// In ru, this message translates to: - /// **'Данные и память'** - String get dataAndStorage; - - /// No description provided for @aboutApp. - /// - /// In ru, this message translates to: - /// **'О приложении'** - String get aboutApp; - - /// No description provided for @help. - /// - /// In ru, this message translates to: - /// **'Помощь'** - String get help; - - /// No description provided for @version. - /// - /// In ru, this message translates to: - /// **'Версия'** - String get version; - - /// No description provided for @loading. - /// - /// In ru, this message translates to: - /// **'Загрузка...'** - String get loading; - - /// No description provided for @error. - /// - /// In ru, this message translates to: - /// **'Ошибка'** - String get error; - - /// No description provided for @retry. - /// - /// In ru, this message translates to: - /// **'Повторить'** - String get retry; - - /// No description provided for @noChats. - /// - /// In ru, this message translates to: - /// **'У вас пока нет чатов'** - String get noChats; - - /// No description provided for @inDevelopment. - /// - /// In ru, this message translates to: - /// **'Функция в разработке'** - String get inDevelopment; - - /// No description provided for @user. - /// - /// In ru, this message translates to: - /// **'Пользователь'** - String get user; - - /// No description provided for @edit. - /// - /// In ru, this message translates to: - /// **'Редактировать'** - String get edit; - - /// No description provided for @serverConnectionError. - /// - /// In ru, this message translates to: - /// **'Ошибка подключения к серверу'** - String get serverConnectionError; - - /// No description provided for @settingsSaved. - /// - /// In ru, this message translates to: - /// **'Настройки сохранены'** - String get settingsSaved; -} - -class _AppLocalizationsDelegate - extends LocalizationsDelegate { - const _AppLocalizationsDelegate(); - - @override - Future load(Locale locale) { - return SynchronousFuture(lookupAppLocalizations(locale)); - } - - @override - bool isSupported(Locale locale) => - ['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.'); -} diff --git a/client-mobile/l10n/app_localizations_en.dart b/client-mobile/l10n/app_localizations_en.dart deleted file mode 100644 index 25720e4..0000000 --- a/client-mobile/l10n/app_localizations_en.dart +++ /dev/null @@ -1,154 +0,0 @@ -// 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 => 'Messenger'; - - @override - String get chats => 'Chats'; - - @override - String get contacts => 'Contacts'; - - @override - String get settings => 'Settings'; - - @override - String get login => 'Login'; - - @override - String get email => 'Email'; - - @override - String get password => 'Password'; - - @override - String get name => 'Name'; - - @override - String get loginButton => 'Sign In'; - - @override - String get register => 'Register'; - - @override - String get noAccount => 'No account? Sign up'; - - @override - String get logout => 'Sign Out'; - - @override - String get serverSettings => 'Server Settings'; - - @override - String get apiUrl => 'API URL'; - - @override - String get apiUrlHint => 'https://api.example.com'; - - @override - String get save => 'Save'; - - @override - String get serverConfig => 'Server Configuration'; - - @override - String get system => 'System'; - - @override - String get stories => 'Stories'; - - @override - String get chatsModule => 'Chats'; - - @override - String get messages => 'Messages'; - - @override - String get calls => 'Calls'; - - @override - String get klipy => 'Klipy'; - - @override - String get import => 'Import'; - - @override - String get federation => 'Federation'; - - @override - String get domainUrl => 'Domain'; - - @override - String get enableRegistration => 'Registration Enabled'; - - @override - String get enabled => 'Enabled'; - - @override - String get disabled => 'Disabled'; - - @override - String get language => 'Language'; - - @override - String get russian => 'Русский'; - - @override - String get english => 'English'; - - @override - String get notifications => 'Notifications'; - - @override - String get privacy => 'Privacy'; - - @override - String get soundsAndVibration => 'Sounds & Vibration'; - - @override - String get dataAndStorage => 'Data & Storage'; - - @override - String get aboutApp => 'About App'; - - @override - String get help => 'Help'; - - @override - String get version => 'Version'; - - @override - String get loading => 'Loading...'; - - @override - String get error => 'Error'; - - @override - String get retry => 'Retry'; - - @override - String get noChats => 'No chats yet'; - - @override - String get inDevelopment => 'In development'; - - @override - String get user => 'User'; - - @override - String get edit => 'Edit'; - - @override - String get serverConnectionError => 'Server connection error'; - - @override - String get settingsSaved => 'Settings saved'; -} diff --git a/client-mobile/l10n/app_localizations_ru.dart b/client-mobile/l10n/app_localizations_ru.dart deleted file mode 100644 index d3fab57..0000000 --- a/client-mobile/l10n/app_localizations_ru.dart +++ /dev/null @@ -1,154 +0,0 @@ -// 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 chats => 'Чаты'; - - @override - String get contacts => 'Контакты'; - - @override - String get settings => 'Настройки'; - - @override - String get login => 'Вход'; - - @override - String get email => 'Email'; - - @override - String get password => 'Пароль'; - - @override - String get name => 'Имя'; - - @override - String get loginButton => 'Войти'; - - @override - String get register => 'Зарегистрироваться'; - - @override - String get noAccount => 'Нет аккаунта? Зарегистрироваться'; - - @override - String get logout => 'Выйти из аккаунта'; - - @override - String get serverSettings => 'Настройки сервера'; - - @override - String get apiUrl => 'Адрес API'; - - @override - String get apiUrlHint => 'https://api.example.com'; - - @override - String get save => 'Сохранить'; - - @override - String get serverConfig => 'Конфигурация сервера'; - - @override - String get system => 'Система'; - - @override - String get stories => 'Истории'; - - @override - String get chatsModule => 'Чаты'; - - @override - String get messages => 'Сообщения'; - - @override - String get calls => 'Звонки'; - - @override - String get klipy => 'Клипы'; - - @override - String get import => 'Импорт'; - - @override - String get federation => 'Федерация'; - - @override - String get domainUrl => 'Домен'; - - @override - String get enableRegistration => 'Регистрация включена'; - - @override - String get enabled => 'Включено'; - - @override - String get disabled => 'Отключено'; - - @override - String get language => 'Язык'; - - @override - String get russian => 'Русский'; - - @override - String get english => 'English'; - - @override - String get notifications => 'Уведомления'; - - @override - String get privacy => 'Конфиденциальность'; - - @override - String get soundsAndVibration => 'Звуки и вибрация'; - - @override - String get dataAndStorage => 'Данные и память'; - - @override - String get aboutApp => 'О приложении'; - - @override - String get help => 'Помощь'; - - @override - String get version => 'Версия'; - - @override - String get loading => 'Загрузка...'; - - @override - String get error => 'Ошибка'; - - @override - String get retry => 'Повторить'; - - @override - String get noChats => 'У вас пока нет чатов'; - - @override - String get inDevelopment => 'Функция в разработке'; - - @override - String get user => 'Пользователь'; - - @override - String get edit => 'Редактировать'; - - @override - String get serverConnectionError => 'Ошибка подключения к серверу'; - - @override - String get settingsSaved => 'Настройки сохранены'; -} diff --git a/client-mobile/l10n/app_ru.arb b/client-mobile/l10n/app_ru.arb index af3143b..c83b62b 100644 --- a/client-mobile/l10n/app_ru.arb +++ b/client-mobile/l10n/app_ru.arb @@ -5,7 +5,7 @@ "contacts": "Контакты", "settings": "Настройки", "login": "Вход", - "email": "Email", + "username": "Логин", "password": "Пароль", "name": "Имя", "loginButton": "Войти", @@ -26,7 +26,7 @@ "import": "Импорт", "federation": "Федерация", "domainUrl": "Домен", - "enableRegistration": "Регистрация включена", + "registrationStatus": "Регистрация", "enabled": "Включено", "disabled": "Отключено", "language": "Язык", @@ -47,5 +47,37 @@ "user": "Пользователь", "edit": "Редактировать", "serverConnectionError": "Ошибка подключения к серверу", - "settingsSaved": "Настройки сохранены" + "connected": "Подключено", + "unknownError": "Неизвестная ошибка", + "networkError": "Ошибка сети", + "serverError": "Ошибка сервера", + "parsingError": "Ошибка обработки данных", + "voice": "Голосовые вызовы", + "video": "Видеовызовы", + "lifetime": "Время жизни", + "groups": "Группы", + "maxParticipants": "Макс. участников", + "hours": "ч.", + "dailyLimit": "Дневной лимит", + "historyLimit": "Лимит истории", + "maxFileSize": "Макс. файл", + "noLimit": "Без лимита", + "allowForwarding": "Пересылка", + "allowReactions": "Реакции", + "allowReplies": "Ответы", + "allowQuoting": "Цитирование", + "allowMessageDeletion": "Удаление", + "forbidCopying": "Запрет копирования", + "allowLinks": "Ссылки", + "allowPolls": "Опросы", + "allowPinning": "Закрепы", + "allowMedia": "Медиа", + "description": "Описание", + "server": "Сервер", + "notSpecified": "не указан", + "settingsSaved": "Настройки сохранены", + "enterUsername": "Введите логин", + "invalidUsername": "Логин должен быть от 3 символов и без кириллицы", + "loginFailed": "Ошибка входа. Проверьте логин и пароль", + "registrationFailed": "Ошибка регистрации" } diff --git a/client-mobile/lib/app.dart b/client-mobile/lib/app.dart index 9cf15ca..e3444a1 100644 --- a/client-mobile/lib/app.dart +++ b/client-mobile/lib/app.dart @@ -1,16 +1,19 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; import 'core/theme/app_theme.dart'; import 'features/auth/presentation/bloc/auth_bloc.dart'; import 'features/auth/presentation/bloc/auth_event.dart'; import 'features/chat/presentation/bloc/chat_bloc.dart'; import 'features/chat/presentation/bloc/chat_event.dart'; +import 'internal/di/injection_container.dart' as di; import 'features/settings/presentation/bloc/settings_bloc.dart'; import 'features/settings/presentation/bloc/settings_event.dart'; import 'features/settings/presentation/bloc/settings_state.dart'; -import 'features/settings/presentation/l10n/app_localizations.dart'; -import 'internal/di/injection_container.dart' as di; +import 'l10n/app_localizations.dart'; import 'internal/router/main_screen.dart'; +import 'features/auth/presentation/pages/login_page.dart'; +import 'features/auth/presentation/bloc/auth_state.dart'; class MessengerApp extends StatelessWidget { const MessengerApp({super.key}); @@ -19,35 +22,48 @@ class MessengerApp extends StatelessWidget { Widget build(BuildContext context) { return MultiBlocProvider( providers: [ - BlocProvider( - create: (_) => di.sl()..add(const SettingsEvent.started()), - ), BlocProvider( create: (_) => di.sl()..add(const AuthEvent.authChecked()), ), BlocProvider( create: (_) => di.sl()..add(const ChatEvent.started()), ), + BlocProvider( + create: (_) => di.sl()..add(const SettingsEvent.started()), + ), ], child: BlocBuilder( - builder: (context, settingsState) { - final languageCode = settingsState is SettingsLoaded - ? settingsState.languageCode - : 'ru'; - + builder: (context, state) { + final locale = state.maybeWhen( + loaded: (_, __, languageCode, ___, ____) => Locale(languageCode), + orElse: () => const Locale('ru'), + ); + return MaterialApp( title: 'Messenger', debugShowCheckedModeBanner: false, theme: AppTheme.lightTheme, darkTheme: AppTheme.darkTheme, themeMode: ThemeMode.system, - locale: Locale(languageCode), + locale: locale, supportedLocales: const [ Locale('ru'), Locale('en'), ], - localizationsDelegates: AppLocalizations.localizationsDelegates, - home: const MainScreen(), + localizationsDelegates: const [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + home: BlocBuilder( + builder: (context, authState) { + return authState.maybeWhen( + authenticated: (_) => const MainScreen(), + orElse: () => const LoginPage(), + ); + }, + ), ); }, ), diff --git a/client-mobile/lib/core/errors/errors.dart b/client-mobile/lib/core/errors/errors.dart index 642547a..4ba5f8d 100644 --- a/client-mobile/lib/core/errors/errors.dart +++ b/client-mobile/lib/core/errors/errors.dart @@ -11,5 +11,6 @@ class AppError with _$AppError { const factory AppError.notFound({String? message}) = NotFoundError; const factory AppError.server({int? statusCode, String? message}) = ServerError; const factory AppError.database({String? message}) = DatabaseError; - const factory AppError.validation({Map? fieldErrors}) = ValidationError; + const factory AppError.validation({String? message, Map? fieldErrors}) = ValidationError; + const factory AppError.parsing({String? message}) = ParsingError; } diff --git a/client-mobile/lib/core/errors/errors.freezed.dart b/client-mobile/lib/core/errors/errors.freezed.dart index cfa537d..8df5dd6 100644 --- a/client-mobile/lib/core/errors/errors.freezed.dart +++ b/client-mobile/lib/core/errors/errors.freezed.dart @@ -16,6 +16,7 @@ final _privateConstructorUsedError = UnsupportedError( /// @nodoc mixin _$AppError { + String? get message => throw _privateConstructorUsedError; @optionalTypeArgs TResult when({ required TResult Function(String? message) unknown, @@ -25,7 +26,9 @@ mixin _$AppError { required TResult Function(String? message) notFound, required TResult Function(int? statusCode, String? message) server, required TResult Function(String? message) database, - required TResult Function(Map? fieldErrors) validation, + required TResult Function(String? message, Map? fieldErrors) + validation, + required TResult Function(String? message) parsing, }) => throw _privateConstructorUsedError; @optionalTypeArgs @@ -37,7 +40,9 @@ mixin _$AppError { TResult? Function(String? message)? notFound, TResult? Function(int? statusCode, String? message)? server, TResult? Function(String? message)? database, - TResult? Function(Map? fieldErrors)? validation, + TResult? Function(String? message, Map? fieldErrors)? + validation, + TResult? Function(String? message)? parsing, }) => throw _privateConstructorUsedError; @optionalTypeArgs @@ -49,7 +54,9 @@ mixin _$AppError { TResult Function(String? message)? notFound, TResult Function(int? statusCode, String? message)? server, TResult Function(String? message)? database, - TResult Function(Map? fieldErrors)? validation, + TResult Function(String? message, Map? fieldErrors)? + validation, + TResult Function(String? message)? parsing, required TResult orElse(), }) => throw _privateConstructorUsedError; @@ -63,6 +70,7 @@ mixin _$AppError { required TResult Function(ServerError value) server, required TResult Function(DatabaseError value) database, required TResult Function(ValidationError value) validation, + required TResult Function(ParsingError value) parsing, }) => throw _privateConstructorUsedError; @optionalTypeArgs @@ -75,6 +83,7 @@ mixin _$AppError { TResult? Function(ServerError value)? server, TResult? Function(DatabaseError value)? database, TResult? Function(ValidationError value)? validation, + TResult? Function(ParsingError value)? parsing, }) => throw _privateConstructorUsedError; @optionalTypeArgs @@ -87,15 +96,22 @@ mixin _$AppError { TResult Function(ServerError value)? server, TResult Function(DatabaseError value)? database, TResult Function(ValidationError value)? validation, + TResult Function(ParsingError value)? parsing, required TResult orElse(), }) => throw _privateConstructorUsedError; + + @JsonKey(ignore: true) + $AppErrorCopyWith get copyWith => + throw _privateConstructorUsedError; } /// @nodoc abstract class $AppErrorCopyWith<$Res> { factory $AppErrorCopyWith(AppError value, $Res Function(AppError) then) = _$AppErrorCopyWithImpl<$Res, AppError>; + @useResult + $Res call({String? message}); } /// @nodoc @@ -107,13 +123,28 @@ class _$AppErrorCopyWithImpl<$Res, $Val extends AppError> final $Val _value; // ignore: unused_field final $Res Function($Val) _then; + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? message = freezed, + }) { + return _then(_value.copyWith( + message: freezed == message + ? _value.message + : message // ignore: cast_nullable_to_non_nullable + as String?, + ) as $Val); + } } /// @nodoc -abstract class _$$UnknownErrorImplCopyWith<$Res> { +abstract class _$$UnknownErrorImplCopyWith<$Res> + implements $AppErrorCopyWith<$Res> { factory _$$UnknownErrorImplCopyWith( _$UnknownErrorImpl value, $Res Function(_$UnknownErrorImpl) then) = __$$UnknownErrorImplCopyWithImpl<$Res>; + @override @useResult $Res call({String? message}); } @@ -180,7 +211,9 @@ class _$UnknownErrorImpl implements UnknownError { required TResult Function(String? message) notFound, required TResult Function(int? statusCode, String? message) server, required TResult Function(String? message) database, - required TResult Function(Map? fieldErrors) validation, + required TResult Function(String? message, Map? fieldErrors) + validation, + required TResult Function(String? message) parsing, }) { return unknown(message); } @@ -195,7 +228,9 @@ class _$UnknownErrorImpl implements UnknownError { TResult? Function(String? message)? notFound, TResult? Function(int? statusCode, String? message)? server, TResult? Function(String? message)? database, - TResult? Function(Map? fieldErrors)? validation, + TResult? Function(String? message, Map? fieldErrors)? + validation, + TResult? Function(String? message)? parsing, }) { return unknown?.call(message); } @@ -210,7 +245,9 @@ class _$UnknownErrorImpl implements UnknownError { TResult Function(String? message)? notFound, TResult Function(int? statusCode, String? message)? server, TResult Function(String? message)? database, - TResult Function(Map? fieldErrors)? validation, + TResult Function(String? message, Map? fieldErrors)? + validation, + TResult Function(String? message)? parsing, required TResult orElse(), }) { if (unknown != null) { @@ -230,6 +267,7 @@ class _$UnknownErrorImpl implements UnknownError { required TResult Function(ServerError value) server, required TResult Function(DatabaseError value) database, required TResult Function(ValidationError value) validation, + required TResult Function(ParsingError value) parsing, }) { return unknown(this); } @@ -245,6 +283,7 @@ class _$UnknownErrorImpl implements UnknownError { TResult? Function(ServerError value)? server, TResult? Function(DatabaseError value)? database, TResult? Function(ValidationError value)? validation, + TResult? Function(ParsingError value)? parsing, }) { return unknown?.call(this); } @@ -260,6 +299,7 @@ class _$UnknownErrorImpl implements UnknownError { TResult Function(ServerError value)? server, TResult Function(DatabaseError value)? database, TResult Function(ValidationError value)? validation, + TResult Function(ParsingError value)? parsing, required TResult orElse(), }) { if (unknown != null) { @@ -272,17 +312,21 @@ class _$UnknownErrorImpl implements UnknownError { abstract class UnknownError implements AppError { const factory UnknownError({final String? message}) = _$UnknownErrorImpl; + @override String? get message; + @override @JsonKey(ignore: true) _$$UnknownErrorImplCopyWith<_$UnknownErrorImpl> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$NetworkErrorImplCopyWith<$Res> { +abstract class _$$NetworkErrorImplCopyWith<$Res> + implements $AppErrorCopyWith<$Res> { factory _$$NetworkErrorImplCopyWith( _$NetworkErrorImpl value, $Res Function(_$NetworkErrorImpl) then) = __$$NetworkErrorImplCopyWithImpl<$Res>; + @override @useResult $Res call({String? message}); } @@ -349,7 +393,9 @@ class _$NetworkErrorImpl implements NetworkError { required TResult Function(String? message) notFound, required TResult Function(int? statusCode, String? message) server, required TResult Function(String? message) database, - required TResult Function(Map? fieldErrors) validation, + required TResult Function(String? message, Map? fieldErrors) + validation, + required TResult Function(String? message) parsing, }) { return network(message); } @@ -364,7 +410,9 @@ class _$NetworkErrorImpl implements NetworkError { TResult? Function(String? message)? notFound, TResult? Function(int? statusCode, String? message)? server, TResult? Function(String? message)? database, - TResult? Function(Map? fieldErrors)? validation, + TResult? Function(String? message, Map? fieldErrors)? + validation, + TResult? Function(String? message)? parsing, }) { return network?.call(message); } @@ -379,7 +427,9 @@ class _$NetworkErrorImpl implements NetworkError { TResult Function(String? message)? notFound, TResult Function(int? statusCode, String? message)? server, TResult Function(String? message)? database, - TResult Function(Map? fieldErrors)? validation, + TResult Function(String? message, Map? fieldErrors)? + validation, + TResult Function(String? message)? parsing, required TResult orElse(), }) { if (network != null) { @@ -399,6 +449,7 @@ class _$NetworkErrorImpl implements NetworkError { required TResult Function(ServerError value) server, required TResult Function(DatabaseError value) database, required TResult Function(ValidationError value) validation, + required TResult Function(ParsingError value) parsing, }) { return network(this); } @@ -414,6 +465,7 @@ class _$NetworkErrorImpl implements NetworkError { TResult? Function(ServerError value)? server, TResult? Function(DatabaseError value)? database, TResult? Function(ValidationError value)? validation, + TResult? Function(ParsingError value)? parsing, }) { return network?.call(this); } @@ -429,6 +481,7 @@ class _$NetworkErrorImpl implements NetworkError { TResult Function(ServerError value)? server, TResult Function(DatabaseError value)? database, TResult Function(ValidationError value)? validation, + TResult Function(ParsingError value)? parsing, required TResult orElse(), }) { if (network != null) { @@ -441,17 +494,21 @@ class _$NetworkErrorImpl implements NetworkError { abstract class NetworkError implements AppError { const factory NetworkError({final String? message}) = _$NetworkErrorImpl; + @override String? get message; + @override @JsonKey(ignore: true) _$$NetworkErrorImplCopyWith<_$NetworkErrorImpl> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$UnauthorizedErrorImplCopyWith<$Res> { +abstract class _$$UnauthorizedErrorImplCopyWith<$Res> + implements $AppErrorCopyWith<$Res> { factory _$$UnauthorizedErrorImplCopyWith(_$UnauthorizedErrorImpl value, $Res Function(_$UnauthorizedErrorImpl) then) = __$$UnauthorizedErrorImplCopyWithImpl<$Res>; + @override @useResult $Res call({String? message}); } @@ -519,7 +576,9 @@ class _$UnauthorizedErrorImpl implements UnauthorizedError { required TResult Function(String? message) notFound, required TResult Function(int? statusCode, String? message) server, required TResult Function(String? message) database, - required TResult Function(Map? fieldErrors) validation, + required TResult Function(String? message, Map? fieldErrors) + validation, + required TResult Function(String? message) parsing, }) { return unauthorized(message); } @@ -534,7 +593,9 @@ class _$UnauthorizedErrorImpl implements UnauthorizedError { TResult? Function(String? message)? notFound, TResult? Function(int? statusCode, String? message)? server, TResult? Function(String? message)? database, - TResult? Function(Map? fieldErrors)? validation, + TResult? Function(String? message, Map? fieldErrors)? + validation, + TResult? Function(String? message)? parsing, }) { return unauthorized?.call(message); } @@ -549,7 +610,9 @@ class _$UnauthorizedErrorImpl implements UnauthorizedError { TResult Function(String? message)? notFound, TResult Function(int? statusCode, String? message)? server, TResult Function(String? message)? database, - TResult Function(Map? fieldErrors)? validation, + TResult Function(String? message, Map? fieldErrors)? + validation, + TResult Function(String? message)? parsing, required TResult orElse(), }) { if (unauthorized != null) { @@ -569,6 +632,7 @@ class _$UnauthorizedErrorImpl implements UnauthorizedError { required TResult Function(ServerError value) server, required TResult Function(DatabaseError value) database, required TResult Function(ValidationError value) validation, + required TResult Function(ParsingError value) parsing, }) { return unauthorized(this); } @@ -584,6 +648,7 @@ class _$UnauthorizedErrorImpl implements UnauthorizedError { TResult? Function(ServerError value)? server, TResult? Function(DatabaseError value)? database, TResult? Function(ValidationError value)? validation, + TResult? Function(ParsingError value)? parsing, }) { return unauthorized?.call(this); } @@ -599,6 +664,7 @@ class _$UnauthorizedErrorImpl implements UnauthorizedError { TResult Function(ServerError value)? server, TResult Function(DatabaseError value)? database, TResult Function(ValidationError value)? validation, + TResult Function(ParsingError value)? parsing, required TResult orElse(), }) { if (unauthorized != null) { @@ -612,17 +678,21 @@ abstract class UnauthorizedError implements AppError { const factory UnauthorizedError({final String? message}) = _$UnauthorizedErrorImpl; + @override String? get message; + @override @JsonKey(ignore: true) _$$UnauthorizedErrorImplCopyWith<_$UnauthorizedErrorImpl> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$ForbiddenErrorImplCopyWith<$Res> { +abstract class _$$ForbiddenErrorImplCopyWith<$Res> + implements $AppErrorCopyWith<$Res> { factory _$$ForbiddenErrorImplCopyWith(_$ForbiddenErrorImpl value, $Res Function(_$ForbiddenErrorImpl) then) = __$$ForbiddenErrorImplCopyWithImpl<$Res>; + @override @useResult $Res call({String? message}); } @@ -690,7 +760,9 @@ class _$ForbiddenErrorImpl implements ForbiddenError { required TResult Function(String? message) notFound, required TResult Function(int? statusCode, String? message) server, required TResult Function(String? message) database, - required TResult Function(Map? fieldErrors) validation, + required TResult Function(String? message, Map? fieldErrors) + validation, + required TResult Function(String? message) parsing, }) { return forbidden(message); } @@ -705,7 +777,9 @@ class _$ForbiddenErrorImpl implements ForbiddenError { TResult? Function(String? message)? notFound, TResult? Function(int? statusCode, String? message)? server, TResult? Function(String? message)? database, - TResult? Function(Map? fieldErrors)? validation, + TResult? Function(String? message, Map? fieldErrors)? + validation, + TResult? Function(String? message)? parsing, }) { return forbidden?.call(message); } @@ -720,7 +794,9 @@ class _$ForbiddenErrorImpl implements ForbiddenError { TResult Function(String? message)? notFound, TResult Function(int? statusCode, String? message)? server, TResult Function(String? message)? database, - TResult Function(Map? fieldErrors)? validation, + TResult Function(String? message, Map? fieldErrors)? + validation, + TResult Function(String? message)? parsing, required TResult orElse(), }) { if (forbidden != null) { @@ -740,6 +816,7 @@ class _$ForbiddenErrorImpl implements ForbiddenError { required TResult Function(ServerError value) server, required TResult Function(DatabaseError value) database, required TResult Function(ValidationError value) validation, + required TResult Function(ParsingError value) parsing, }) { return forbidden(this); } @@ -755,6 +832,7 @@ class _$ForbiddenErrorImpl implements ForbiddenError { TResult? Function(ServerError value)? server, TResult? Function(DatabaseError value)? database, TResult? Function(ValidationError value)? validation, + TResult? Function(ParsingError value)? parsing, }) { return forbidden?.call(this); } @@ -770,6 +848,7 @@ class _$ForbiddenErrorImpl implements ForbiddenError { TResult Function(ServerError value)? server, TResult Function(DatabaseError value)? database, TResult Function(ValidationError value)? validation, + TResult Function(ParsingError value)? parsing, required TResult orElse(), }) { if (forbidden != null) { @@ -782,17 +861,21 @@ class _$ForbiddenErrorImpl implements ForbiddenError { abstract class ForbiddenError implements AppError { const factory ForbiddenError({final String? message}) = _$ForbiddenErrorImpl; + @override String? get message; + @override @JsonKey(ignore: true) _$$ForbiddenErrorImplCopyWith<_$ForbiddenErrorImpl> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$NotFoundErrorImplCopyWith<$Res> { +abstract class _$$NotFoundErrorImplCopyWith<$Res> + implements $AppErrorCopyWith<$Res> { factory _$$NotFoundErrorImplCopyWith( _$NotFoundErrorImpl value, $Res Function(_$NotFoundErrorImpl) then) = __$$NotFoundErrorImplCopyWithImpl<$Res>; + @override @useResult $Res call({String? message}); } @@ -859,7 +942,9 @@ class _$NotFoundErrorImpl implements NotFoundError { required TResult Function(String? message) notFound, required TResult Function(int? statusCode, String? message) server, required TResult Function(String? message) database, - required TResult Function(Map? fieldErrors) validation, + required TResult Function(String? message, Map? fieldErrors) + validation, + required TResult Function(String? message) parsing, }) { return notFound(message); } @@ -874,7 +959,9 @@ class _$NotFoundErrorImpl implements NotFoundError { TResult? Function(String? message)? notFound, TResult? Function(int? statusCode, String? message)? server, TResult? Function(String? message)? database, - TResult? Function(Map? fieldErrors)? validation, + TResult? Function(String? message, Map? fieldErrors)? + validation, + TResult? Function(String? message)? parsing, }) { return notFound?.call(message); } @@ -889,7 +976,9 @@ class _$NotFoundErrorImpl implements NotFoundError { TResult Function(String? message)? notFound, TResult Function(int? statusCode, String? message)? server, TResult Function(String? message)? database, - TResult Function(Map? fieldErrors)? validation, + TResult Function(String? message, Map? fieldErrors)? + validation, + TResult Function(String? message)? parsing, required TResult orElse(), }) { if (notFound != null) { @@ -909,6 +998,7 @@ class _$NotFoundErrorImpl implements NotFoundError { required TResult Function(ServerError value) server, required TResult Function(DatabaseError value) database, required TResult Function(ValidationError value) validation, + required TResult Function(ParsingError value) parsing, }) { return notFound(this); } @@ -924,6 +1014,7 @@ class _$NotFoundErrorImpl implements NotFoundError { TResult? Function(ServerError value)? server, TResult? Function(DatabaseError value)? database, TResult? Function(ValidationError value)? validation, + TResult? Function(ParsingError value)? parsing, }) { return notFound?.call(this); } @@ -939,6 +1030,7 @@ class _$NotFoundErrorImpl implements NotFoundError { TResult Function(ServerError value)? server, TResult Function(DatabaseError value)? database, TResult Function(ValidationError value)? validation, + TResult Function(ParsingError value)? parsing, required TResult orElse(), }) { if (notFound != null) { @@ -951,17 +1043,21 @@ class _$NotFoundErrorImpl implements NotFoundError { abstract class NotFoundError implements AppError { const factory NotFoundError({final String? message}) = _$NotFoundErrorImpl; + @override String? get message; + @override @JsonKey(ignore: true) _$$NotFoundErrorImplCopyWith<_$NotFoundErrorImpl> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$ServerErrorImplCopyWith<$Res> { +abstract class _$$ServerErrorImplCopyWith<$Res> + implements $AppErrorCopyWith<$Res> { factory _$$ServerErrorImplCopyWith( _$ServerErrorImpl value, $Res Function(_$ServerErrorImpl) then) = __$$ServerErrorImplCopyWithImpl<$Res>; + @override @useResult $Res call({int? statusCode, String? message}); } @@ -1037,7 +1133,9 @@ class _$ServerErrorImpl implements ServerError { required TResult Function(String? message) notFound, required TResult Function(int? statusCode, String? message) server, required TResult Function(String? message) database, - required TResult Function(Map? fieldErrors) validation, + required TResult Function(String? message, Map? fieldErrors) + validation, + required TResult Function(String? message) parsing, }) { return server(statusCode, message); } @@ -1052,7 +1150,9 @@ class _$ServerErrorImpl implements ServerError { TResult? Function(String? message)? notFound, TResult? Function(int? statusCode, String? message)? server, TResult? Function(String? message)? database, - TResult? Function(Map? fieldErrors)? validation, + TResult? Function(String? message, Map? fieldErrors)? + validation, + TResult? Function(String? message)? parsing, }) { return server?.call(statusCode, message); } @@ -1067,7 +1167,9 @@ class _$ServerErrorImpl implements ServerError { TResult Function(String? message)? notFound, TResult Function(int? statusCode, String? message)? server, TResult Function(String? message)? database, - TResult Function(Map? fieldErrors)? validation, + TResult Function(String? message, Map? fieldErrors)? + validation, + TResult Function(String? message)? parsing, required TResult orElse(), }) { if (server != null) { @@ -1087,6 +1189,7 @@ class _$ServerErrorImpl implements ServerError { required TResult Function(ServerError value) server, required TResult Function(DatabaseError value) database, required TResult Function(ValidationError value) validation, + required TResult Function(ParsingError value) parsing, }) { return server(this); } @@ -1102,6 +1205,7 @@ class _$ServerErrorImpl implements ServerError { TResult? Function(ServerError value)? server, TResult? Function(DatabaseError value)? database, TResult? Function(ValidationError value)? validation, + TResult? Function(ParsingError value)? parsing, }) { return server?.call(this); } @@ -1117,6 +1221,7 @@ class _$ServerErrorImpl implements ServerError { TResult Function(ServerError value)? server, TResult Function(DatabaseError value)? database, TResult Function(ValidationError value)? validation, + TResult Function(ParsingError value)? parsing, required TResult orElse(), }) { if (server != null) { @@ -1131,17 +1236,21 @@ abstract class ServerError implements AppError { _$ServerErrorImpl; int? get statusCode; + @override String? get message; + @override @JsonKey(ignore: true) _$$ServerErrorImplCopyWith<_$ServerErrorImpl> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$DatabaseErrorImplCopyWith<$Res> { +abstract class _$$DatabaseErrorImplCopyWith<$Res> + implements $AppErrorCopyWith<$Res> { factory _$$DatabaseErrorImplCopyWith( _$DatabaseErrorImpl value, $Res Function(_$DatabaseErrorImpl) then) = __$$DatabaseErrorImplCopyWithImpl<$Res>; + @override @useResult $Res call({String? message}); } @@ -1208,7 +1317,9 @@ class _$DatabaseErrorImpl implements DatabaseError { required TResult Function(String? message) notFound, required TResult Function(int? statusCode, String? message) server, required TResult Function(String? message) database, - required TResult Function(Map? fieldErrors) validation, + required TResult Function(String? message, Map? fieldErrors) + validation, + required TResult Function(String? message) parsing, }) { return database(message); } @@ -1223,7 +1334,9 @@ class _$DatabaseErrorImpl implements DatabaseError { TResult? Function(String? message)? notFound, TResult? Function(int? statusCode, String? message)? server, TResult? Function(String? message)? database, - TResult? Function(Map? fieldErrors)? validation, + TResult? Function(String? message, Map? fieldErrors)? + validation, + TResult? Function(String? message)? parsing, }) { return database?.call(message); } @@ -1238,7 +1351,9 @@ class _$DatabaseErrorImpl implements DatabaseError { TResult Function(String? message)? notFound, TResult Function(int? statusCode, String? message)? server, TResult Function(String? message)? database, - TResult Function(Map? fieldErrors)? validation, + TResult Function(String? message, Map? fieldErrors)? + validation, + TResult Function(String? message)? parsing, required TResult orElse(), }) { if (database != null) { @@ -1258,6 +1373,7 @@ class _$DatabaseErrorImpl implements DatabaseError { required TResult Function(ServerError value) server, required TResult Function(DatabaseError value) database, required TResult Function(ValidationError value) validation, + required TResult Function(ParsingError value) parsing, }) { return database(this); } @@ -1273,6 +1389,7 @@ class _$DatabaseErrorImpl implements DatabaseError { TResult? Function(ServerError value)? server, TResult? Function(DatabaseError value)? database, TResult? Function(ValidationError value)? validation, + TResult? Function(ParsingError value)? parsing, }) { return database?.call(this); } @@ -1288,6 +1405,7 @@ class _$DatabaseErrorImpl implements DatabaseError { TResult Function(ServerError value)? server, TResult Function(DatabaseError value)? database, TResult Function(ValidationError value)? validation, + TResult Function(ParsingError value)? parsing, required TResult orElse(), }) { if (database != null) { @@ -1300,19 +1418,23 @@ class _$DatabaseErrorImpl implements DatabaseError { abstract class DatabaseError implements AppError { const factory DatabaseError({final String? message}) = _$DatabaseErrorImpl; + @override String? get message; + @override @JsonKey(ignore: true) _$$DatabaseErrorImplCopyWith<_$DatabaseErrorImpl> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$ValidationErrorImplCopyWith<$Res> { +abstract class _$$ValidationErrorImplCopyWith<$Res> + implements $AppErrorCopyWith<$Res> { factory _$$ValidationErrorImplCopyWith(_$ValidationErrorImpl value, $Res Function(_$ValidationErrorImpl) then) = __$$ValidationErrorImplCopyWithImpl<$Res>; + @override @useResult - $Res call({Map? fieldErrors}); + $Res call({String? message, Map? fieldErrors}); } /// @nodoc @@ -1326,9 +1448,14 @@ class __$$ValidationErrorImplCopyWithImpl<$Res> @pragma('vm:prefer-inline') @override $Res call({ + Object? message = freezed, Object? fieldErrors = freezed, }) { return _then(_$ValidationErrorImpl( + message: freezed == message + ? _value.message + : message // ignore: cast_nullable_to_non_nullable + as String?, fieldErrors: freezed == fieldErrors ? _value._fieldErrors : fieldErrors // ignore: cast_nullable_to_non_nullable @@ -1340,9 +1467,12 @@ class __$$ValidationErrorImplCopyWithImpl<$Res> /// @nodoc class _$ValidationErrorImpl implements ValidationError { - const _$ValidationErrorImpl({final Map? fieldErrors}) + const _$ValidationErrorImpl( + {this.message, final Map? fieldErrors}) : _fieldErrors = fieldErrors; + @override + final String? message; final Map? _fieldErrors; @override Map? get fieldErrors { @@ -1355,7 +1485,7 @@ class _$ValidationErrorImpl implements ValidationError { @override String toString() { - return 'AppError.validation(fieldErrors: $fieldErrors)'; + return 'AppError.validation(message: $message, fieldErrors: $fieldErrors)'; } @override @@ -1363,13 +1493,14 @@ class _$ValidationErrorImpl implements ValidationError { return identical(this, other) || (other.runtimeType == runtimeType && other is _$ValidationErrorImpl && + (identical(other.message, message) || other.message == message) && const DeepCollectionEquality() .equals(other._fieldErrors, _fieldErrors)); } @override int get hashCode => Object.hash( - runtimeType, const DeepCollectionEquality().hash(_fieldErrors)); + runtimeType, message, const DeepCollectionEquality().hash(_fieldErrors)); @JsonKey(ignore: true) @override @@ -1388,9 +1519,11 @@ class _$ValidationErrorImpl implements ValidationError { required TResult Function(String? message) notFound, required TResult Function(int? statusCode, String? message) server, required TResult Function(String? message) database, - required TResult Function(Map? fieldErrors) validation, + required TResult Function(String? message, Map? fieldErrors) + validation, + required TResult Function(String? message) parsing, }) { - return validation(fieldErrors); + return validation(message, fieldErrors); } @override @@ -1403,9 +1536,11 @@ class _$ValidationErrorImpl implements ValidationError { TResult? Function(String? message)? notFound, TResult? Function(int? statusCode, String? message)? server, TResult? Function(String? message)? database, - TResult? Function(Map? fieldErrors)? validation, + TResult? Function(String? message, Map? fieldErrors)? + validation, + TResult? Function(String? message)? parsing, }) { - return validation?.call(fieldErrors); + return validation?.call(message, fieldErrors); } @override @@ -1418,11 +1553,13 @@ class _$ValidationErrorImpl implements ValidationError { TResult Function(String? message)? notFound, TResult Function(int? statusCode, String? message)? server, TResult Function(String? message)? database, - TResult Function(Map? fieldErrors)? validation, + TResult Function(String? message, Map? fieldErrors)? + validation, + TResult Function(String? message)? parsing, required TResult orElse(), }) { if (validation != null) { - return validation(fieldErrors); + return validation(message, fieldErrors); } return orElse(); } @@ -1438,6 +1575,7 @@ class _$ValidationErrorImpl implements ValidationError { required TResult Function(ServerError value) server, required TResult Function(DatabaseError value) database, required TResult Function(ValidationError value) validation, + required TResult Function(ParsingError value) parsing, }) { return validation(this); } @@ -1453,6 +1591,7 @@ class _$ValidationErrorImpl implements ValidationError { TResult? Function(ServerError value)? server, TResult? Function(DatabaseError value)? database, TResult? Function(ValidationError value)? validation, + TResult? Function(ParsingError value)? parsing, }) { return validation?.call(this); } @@ -1468,6 +1607,7 @@ class _$ValidationErrorImpl implements ValidationError { TResult Function(ServerError value)? server, TResult Function(DatabaseError value)? database, TResult Function(ValidationError value)? validation, + TResult Function(ParsingError value)? parsing, required TResult orElse(), }) { if (validation != null) { @@ -1478,11 +1618,197 @@ class _$ValidationErrorImpl implements ValidationError { } abstract class ValidationError implements AppError { - const factory ValidationError({final Map? fieldErrors}) = - _$ValidationErrorImpl; + const factory ValidationError( + {final String? message, + final Map? fieldErrors}) = _$ValidationErrorImpl; + @override + String? get message; Map? get fieldErrors; + @override @JsonKey(ignore: true) _$$ValidationErrorImplCopyWith<_$ValidationErrorImpl> get copyWith => throw _privateConstructorUsedError; } + +/// @nodoc +abstract class _$$ParsingErrorImplCopyWith<$Res> + implements $AppErrorCopyWith<$Res> { + factory _$$ParsingErrorImplCopyWith( + _$ParsingErrorImpl value, $Res Function(_$ParsingErrorImpl) then) = + __$$ParsingErrorImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({String? message}); +} + +/// @nodoc +class __$$ParsingErrorImplCopyWithImpl<$Res> + extends _$AppErrorCopyWithImpl<$Res, _$ParsingErrorImpl> + implements _$$ParsingErrorImplCopyWith<$Res> { + __$$ParsingErrorImplCopyWithImpl( + _$ParsingErrorImpl _value, $Res Function(_$ParsingErrorImpl) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? message = freezed, + }) { + return _then(_$ParsingErrorImpl( + message: freezed == message + ? _value.message + : message // ignore: cast_nullable_to_non_nullable + as String?, + )); + } +} + +/// @nodoc + +class _$ParsingErrorImpl implements ParsingError { + const _$ParsingErrorImpl({this.message}); + + @override + final String? message; + + @override + String toString() { + return 'AppError.parsing(message: $message)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ParsingErrorImpl && + (identical(other.message, message) || other.message == message)); + } + + @override + int get hashCode => Object.hash(runtimeType, message); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$ParsingErrorImplCopyWith<_$ParsingErrorImpl> get copyWith => + __$$ParsingErrorImplCopyWithImpl<_$ParsingErrorImpl>(this, _$identity); + + @override + @optionalTypeArgs + TResult when({ + required TResult Function(String? message) unknown, + required TResult Function(String? message) network, + required TResult Function(String? message) unauthorized, + required TResult Function(String? message) forbidden, + required TResult Function(String? message) notFound, + required TResult Function(int? statusCode, String? message) server, + required TResult Function(String? message) database, + required TResult Function(String? message, Map? fieldErrors) + validation, + required TResult Function(String? message) parsing, + }) { + return parsing(message); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function(String? message)? unknown, + TResult? Function(String? message)? network, + TResult? Function(String? message)? unauthorized, + TResult? Function(String? message)? forbidden, + TResult? Function(String? message)? notFound, + TResult? Function(int? statusCode, String? message)? server, + TResult? Function(String? message)? database, + TResult? Function(String? message, Map? fieldErrors)? + validation, + TResult? Function(String? message)? parsing, + }) { + return parsing?.call(message); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function(String? message)? unknown, + TResult Function(String? message)? network, + TResult Function(String? message)? unauthorized, + TResult Function(String? message)? forbidden, + TResult Function(String? message)? notFound, + TResult Function(int? statusCode, String? message)? server, + TResult Function(String? message)? database, + TResult Function(String? message, Map? fieldErrors)? + validation, + TResult Function(String? message)? parsing, + required TResult orElse(), + }) { + if (parsing != null) { + return parsing(message); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(UnknownError value) unknown, + required TResult Function(NetworkError value) network, + required TResult Function(UnauthorizedError value) unauthorized, + required TResult Function(ForbiddenError value) forbidden, + required TResult Function(NotFoundError value) notFound, + required TResult Function(ServerError value) server, + required TResult Function(DatabaseError value) database, + required TResult Function(ValidationError value) validation, + required TResult Function(ParsingError value) parsing, + }) { + return parsing(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(UnknownError value)? unknown, + TResult? Function(NetworkError value)? network, + TResult? Function(UnauthorizedError value)? unauthorized, + TResult? Function(ForbiddenError value)? forbidden, + TResult? Function(NotFoundError value)? notFound, + TResult? Function(ServerError value)? server, + TResult? Function(DatabaseError value)? database, + TResult? Function(ValidationError value)? validation, + TResult? Function(ParsingError value)? parsing, + }) { + return parsing?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(UnknownError value)? unknown, + TResult Function(NetworkError value)? network, + TResult Function(UnauthorizedError value)? unauthorized, + TResult Function(ForbiddenError value)? forbidden, + TResult Function(NotFoundError value)? notFound, + TResult Function(ServerError value)? server, + TResult Function(DatabaseError value)? database, + TResult Function(ValidationError value)? validation, + TResult Function(ParsingError value)? parsing, + required TResult orElse(), + }) { + if (parsing != null) { + return parsing(this); + } + return orElse(); + } +} + +abstract class ParsingError implements AppError { + const factory ParsingError({final String? message}) = _$ParsingErrorImpl; + + @override + String? get message; + @override + @JsonKey(ignore: true) + _$$ParsingErrorImplCopyWith<_$ParsingErrorImpl> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/client-mobile/lib/core/errors/result.dart b/client-mobile/lib/core/errors/result.dart index b214d68..4282e8d 100644 --- a/client-mobile/lib/core/errors/result.dart +++ b/client-mobile/lib/core/errors/result.dart @@ -21,6 +21,23 @@ class Result { return onFailure(error!); } + R fold( + R Function(AppError error) onFailure, + R Function(T data) onSuccess, + ) { + if (isSuccess) { + return onSuccess(data as T); + } + return onFailure(error!); + } + + Result map(R Function(T data) transform) { + if (isSuccess) { + return Result.success(transform(data as T)); + } + return Result.failure(error!); + } + T getOrThrow() { if (isFailure) { throw error!; diff --git a/client-mobile/lib/features/auth/data/datasources/auth_local_datasource.dart b/client-mobile/lib/features/auth/data/datasources/auth_local_datasource.dart index 02af6d7..4604e43 100644 --- a/client-mobile/lib/features/auth/data/datasources/auth_local_datasource.dart +++ b/client-mobile/lib/features/auth/data/datasources/auth_local_datasource.dart @@ -1,6 +1,8 @@ abstract class AuthLocalDataSource { Future getToken(); Future saveToken(String token); + Future getRefreshToken(); + Future saveRefreshToken(String token); Future removeToken(); Future getUserId(); Future saveUserId(String userId); diff --git a/client-mobile/lib/features/auth/data/datasources/auth_local_datasource_impl.dart b/client-mobile/lib/features/auth/data/datasources/auth_local_datasource_impl.dart new file mode 100644 index 0000000..b16d33f --- /dev/null +++ b/client-mobile/lib/features/auth/data/datasources/auth_local_datasource_impl.dart @@ -0,0 +1,51 @@ +import 'package:shared_preferences/shared_preferences.dart'; +import 'auth_local_datasource.dart'; + +class AuthLocalDataSourceImpl implements AuthLocalDataSource { + final SharedPreferences sharedPreferences; + + static const String _accessTokenKey = 'access_token'; + static const String _refreshTokenKey = 'refresh_token'; + static const String _userIdKey = 'user_id'; + + AuthLocalDataSourceImpl(this.sharedPreferences); + + @override + Future getToken() async { + return sharedPreferences.getString(_accessTokenKey); + } + + Future getRefreshToken() async { + return sharedPreferences.getString(_refreshTokenKey); + } + + @override + Future saveToken(String token) async { + await sharedPreferences.setString(_accessTokenKey, token); + } + + Future saveRefreshToken(String token) async { + await sharedPreferences.setString(_refreshTokenKey, token); + } + + @override + Future removeToken() async { + await sharedPreferences.remove(_accessTokenKey); + await sharedPreferences.remove(_refreshTokenKey); + } + + @override + Future getUserId() async { + return sharedPreferences.getString(_userIdKey); + } + + @override + Future saveUserId(String userId) async { + await sharedPreferences.setString(_userIdKey, userId); + } + + @override + Future removeUserId() async { + await sharedPreferences.remove(_userIdKey); + } +} diff --git a/client-mobile/lib/features/auth/data/datasources/auth_remote_datasource.dart b/client-mobile/lib/features/auth/data/datasources/auth_remote_datasource.dart index 707bc63..60e340b 100644 --- a/client-mobile/lib/features/auth/data/datasources/auth_remote_datasource.dart +++ b/client-mobile/lib/features/auth/data/datasources/auth_remote_datasource.dart @@ -1,9 +1,10 @@ import '../../../../core/errors/result.dart'; import '../../domain/entities/user.dart'; +import '../models/auth_response.dart'; abstract class AuthRemoteDataSource { - Future> login(String email, String password); - Future> register(String email, String password, String name); + Future> login(String username, String password); + Future> register(String username, String password, String name); Future> logout(); Future> getCurrentUser(); Future> refreshToken(); diff --git a/client-mobile/lib/features/auth/data/datasources/auth_remote_datasource_impl.dart b/client-mobile/lib/features/auth/data/datasources/auth_remote_datasource_impl.dart new file mode 100644 index 0000000..b61a7a2 --- /dev/null +++ b/client-mobile/lib/features/auth/data/datasources/auth_remote_datasource_impl.dart @@ -0,0 +1,87 @@ +import '../../../../core/errors/errors.dart'; +import '../../../../core/network/api_client.dart'; +import '../../../../core/errors/result.dart'; +import '../../domain/entities/user.dart'; +import '../models/auth_response.dart'; +import 'auth_remote_datasource.dart'; + +class AuthRemoteDataSourceImpl implements AuthRemoteDataSource { + final ApiClient apiClient; + + AuthRemoteDataSourceImpl(this.apiClient); + + @override + Future> login(String username, String password) async { + final result = await apiClient.post>( + '/api/auth/login', + data: { + 'username': username, + 'password': password, + }, + ); + + return result.fold( + (error) => Result.failure(error), + (data) { + try { + return Result.success(AuthResponse.fromJson(data)); + } catch (e) { + return Result.failure(AppError.parsing(message: 'Invalid server response format: $e')); + } + }, + ); + } + + @override + Future> register(String username, String password, String name) async { + final result = await apiClient.post>( + '/api/auth/register', + data: { + 'username': username, + 'password': password, + 'displayName': name, + }, + ); + + return result.fold( + (error) => Result.failure(error), + (data) { + try { + return Result.success(AuthResponse.fromJson(data)); + } catch (e) { + return Result.failure(AppError.parsing(message: 'Invalid server response format: $e')); + } + }, + ); + } + + @override + Future> logout() async { + return await apiClient.post('/api/auth/logout'); + } + + @override + Future> getCurrentUser() async { + final result = await apiClient.get>('/api/auth/me'); + return result.fold( + (error) => Result.failure(error), + (data) { + try { + return Result.success(User( + id: data['userId'] as String, + email: data['username'] as String, + name: data['displayName'] as String, + avatarUrl: data['avatar'] as String?, + )); + } catch (e) { + return Result.failure(AppError.parsing(message: 'Invalid user data format: $e')); + } + }, + ); + } + + @override + Future> refreshToken() async { + return await apiClient.post('/api/auth/refresh'); + } +} diff --git a/client-mobile/lib/features/auth/data/models/auth_response.dart b/client-mobile/lib/features/auth/data/models/auth_response.dart new file mode 100644 index 0000000..26a93cf --- /dev/null +++ b/client-mobile/lib/features/auth/data/models/auth_response.dart @@ -0,0 +1,30 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; +import '../../domain/entities/user.dart'; + +part 'auth_response.freezed.dart'; +part 'auth_response.g.dart'; + +@freezed +class AuthResponse with _$AuthResponse { + const factory AuthResponse({ + required String accessToken, + required String refreshToken, + required String userId, + required String username, + required String displayName, + }) = _AuthResponse; + + const AuthResponse._(); + + factory AuthResponse.fromJson(Map json) => + _$AuthResponseFromJson(json); + + // Helper to convert to domain User + User toDomainUser() { + return User( + id: userId, + email: username, // Использование логина как email в сущности User + name: displayName, + ); + } +} diff --git a/client-mobile/lib/features/auth/data/models/auth_response.freezed.dart b/client-mobile/lib/features/auth/data/models/auth_response.freezed.dart new file mode 100644 index 0000000..be09d94 --- /dev/null +++ b/client-mobile/lib/features/auth/data/models/auth_response.freezed.dart @@ -0,0 +1,242 @@ +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'auth_response.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); + +AuthResponse _$AuthResponseFromJson(Map json) { + return _AuthResponse.fromJson(json); +} + +/// @nodoc +mixin _$AuthResponse { + String get accessToken => throw _privateConstructorUsedError; + String get refreshToken => throw _privateConstructorUsedError; + String get userId => throw _privateConstructorUsedError; + String get username => throw _privateConstructorUsedError; + String get displayName => throw _privateConstructorUsedError; + + Map toJson() => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + $AuthResponseCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $AuthResponseCopyWith<$Res> { + factory $AuthResponseCopyWith( + AuthResponse value, $Res Function(AuthResponse) then) = + _$AuthResponseCopyWithImpl<$Res, AuthResponse>; + @useResult + $Res call( + {String accessToken, + String refreshToken, + String userId, + String username, + String displayName}); +} + +/// @nodoc +class _$AuthResponseCopyWithImpl<$Res, $Val extends AuthResponse> + implements $AuthResponseCopyWith<$Res> { + _$AuthResponseCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? accessToken = null, + Object? refreshToken = null, + Object? userId = null, + Object? username = null, + Object? displayName = null, + }) { + return _then(_value.copyWith( + accessToken: null == accessToken + ? _value.accessToken + : accessToken // ignore: cast_nullable_to_non_nullable + as String, + refreshToken: null == refreshToken + ? _value.refreshToken + : refreshToken // ignore: cast_nullable_to_non_nullable + as String, + userId: null == userId + ? _value.userId + : userId // ignore: cast_nullable_to_non_nullable + as String, + username: null == username + ? _value.username + : username // ignore: cast_nullable_to_non_nullable + as String, + displayName: null == displayName + ? _value.displayName + : displayName // ignore: cast_nullable_to_non_nullable + as String, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$AuthResponseImplCopyWith<$Res> + implements $AuthResponseCopyWith<$Res> { + factory _$$AuthResponseImplCopyWith( + _$AuthResponseImpl value, $Res Function(_$AuthResponseImpl) then) = + __$$AuthResponseImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {String accessToken, + String refreshToken, + String userId, + String username, + String displayName}); +} + +/// @nodoc +class __$$AuthResponseImplCopyWithImpl<$Res> + extends _$AuthResponseCopyWithImpl<$Res, _$AuthResponseImpl> + implements _$$AuthResponseImplCopyWith<$Res> { + __$$AuthResponseImplCopyWithImpl( + _$AuthResponseImpl _value, $Res Function(_$AuthResponseImpl) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? accessToken = null, + Object? refreshToken = null, + Object? userId = null, + Object? username = null, + Object? displayName = null, + }) { + return _then(_$AuthResponseImpl( + accessToken: null == accessToken + ? _value.accessToken + : accessToken // ignore: cast_nullable_to_non_nullable + as String, + refreshToken: null == refreshToken + ? _value.refreshToken + : refreshToken // ignore: cast_nullable_to_non_nullable + as String, + userId: null == userId + ? _value.userId + : userId // ignore: cast_nullable_to_non_nullable + as String, + username: null == username + ? _value.username + : username // ignore: cast_nullable_to_non_nullable + as String, + displayName: null == displayName + ? _value.displayName + : displayName // ignore: cast_nullable_to_non_nullable + as String, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$AuthResponseImpl extends _AuthResponse { + const _$AuthResponseImpl( + {required this.accessToken, + required this.refreshToken, + required this.userId, + required this.username, + required this.displayName}) + : super._(); + + factory _$AuthResponseImpl.fromJson(Map json) => + _$$AuthResponseImplFromJson(json); + + @override + final String accessToken; + @override + final String refreshToken; + @override + final String userId; + @override + final String username; + @override + final String displayName; + + @override + String toString() { + return 'AuthResponse(accessToken: $accessToken, refreshToken: $refreshToken, userId: $userId, username: $username, displayName: $displayName)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$AuthResponseImpl && + (identical(other.accessToken, accessToken) || + other.accessToken == accessToken) && + (identical(other.refreshToken, refreshToken) || + other.refreshToken == refreshToken) && + (identical(other.userId, userId) || other.userId == userId) && + (identical(other.username, username) || + other.username == username) && + (identical(other.displayName, displayName) || + other.displayName == displayName)); + } + + @JsonKey(ignore: true) + @override + int get hashCode => Object.hash( + runtimeType, accessToken, refreshToken, userId, username, displayName); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$AuthResponseImplCopyWith<_$AuthResponseImpl> get copyWith => + __$$AuthResponseImplCopyWithImpl<_$AuthResponseImpl>(this, _$identity); + + @override + Map toJson() { + return _$$AuthResponseImplToJson( + this, + ); + } +} + +abstract class _AuthResponse extends AuthResponse { + const factory _AuthResponse( + {required final String accessToken, + required final String refreshToken, + required final String userId, + required final String username, + required final String displayName}) = _$AuthResponseImpl; + const _AuthResponse._() : super._(); + + factory _AuthResponse.fromJson(Map json) = + _$AuthResponseImpl.fromJson; + + @override + String get accessToken; + @override + String get refreshToken; + @override + String get userId; + @override + String get username; + @override + String get displayName; + @override + @JsonKey(ignore: true) + _$$AuthResponseImplCopyWith<_$AuthResponseImpl> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/client-mobile/lib/features/auth/data/models/auth_response.g.dart b/client-mobile/lib/features/auth/data/models/auth_response.g.dart new file mode 100644 index 0000000..7f835c3 --- /dev/null +++ b/client-mobile/lib/features/auth/data/models/auth_response.g.dart @@ -0,0 +1,25 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'auth_response.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_$AuthResponseImpl _$$AuthResponseImplFromJson(Map json) => + _$AuthResponseImpl( + accessToken: json['accessToken'] as String, + refreshToken: json['refreshToken'] as String, + userId: json['userId'] as String, + username: json['username'] as String, + displayName: json['displayName'] as String, + ); + +Map _$$AuthResponseImplToJson(_$AuthResponseImpl instance) => + { + 'accessToken': instance.accessToken, + 'refreshToken': instance.refreshToken, + 'userId': instance.userId, + 'username': instance.username, + 'displayName': instance.displayName, + }; diff --git a/client-mobile/lib/features/auth/data/repositories/auth_repository_impl.dart b/client-mobile/lib/features/auth/data/repositories/auth_repository_impl.dart index 683576f..e50839a 100644 --- a/client-mobile/lib/features/auth/data/repositories/auth_repository_impl.dart +++ b/client-mobile/lib/features/auth/data/repositories/auth_repository_impl.dart @@ -1,47 +1,64 @@ -import '../../../../core/errors/errors.dart'; import '../../../../core/errors/result.dart'; import '../../domain/entities/user.dart'; import '../../domain/repositories/auth_repository.dart'; +import '../datasources/auth_local_datasource.dart'; +import '../datasources/auth_remote_datasource.dart'; class AuthRepositoryImpl implements AuthRepository { - @override - bool get isLoggedIn => false; + final AuthRemoteDataSource remoteDataSource; + final AuthLocalDataSource localDataSource; + + AuthRepositoryImpl({ + required this.remoteDataSource, + required this.localDataSource, + }); @override - Future> getCurrentUser() async { - return const Result.failure(AppError.unauthorized(message: 'Not logged in')); + Future> login(String username, String password) async { + final result = await remoteDataSource.login(username, password); + return result.fold( + (error) => Result.failure(error), + (response) async { + await localDataSource.saveToken(response.accessToken); + await localDataSource.saveRefreshToken(response.refreshToken); + await localDataSource.saveUserId(response.userId); + return Result.success(response.toDomainUser()); + }, + ); } @override - Future> login(String email, String password) async { - // TODO: Implement real login - return Result.success( - User( - id: '1', - email: email, - name: 'Test User', - ), + Future> register(String username, String password, String name) async { + final result = await remoteDataSource.register(username, password, name); + return result.fold( + (error) => Result.failure(error), + (response) async { + await localDataSource.saveToken(response.accessToken); + await localDataSource.saveRefreshToken(response.refreshToken); + await localDataSource.saveUserId(response.userId); + return Result.success(response.toDomainUser()); + }, ); } @override Future> logout() async { + await remoteDataSource.logout(); + await localDataSource.removeToken(); + await localDataSource.removeUserId(); return const Result.success(null); } @override - Future> register(String email, String password, String name) async { - return Result.success( - User( - id: '1', - email: email, - name: name, - ), - ); + Future> getCurrentUser() async { + return await remoteDataSource.getCurrentUser(); } @override Future> refreshToken() async { - return const Result.success(null); + return await remoteDataSource.refreshToken(); } + + @override + bool get isLoggedIn => false; } diff --git a/client-mobile/lib/features/auth/domain/entities/user.dart b/client-mobile/lib/features/auth/domain/entities/user.dart index 4b41608..d05db9f 100644 --- a/client-mobile/lib/features/auth/domain/entities/user.dart +++ b/client-mobile/lib/features/auth/domain/entities/user.dart @@ -1,7 +1,7 @@ import 'package:freezed_annotation/freezed_annotation.dart'; part 'user.freezed.dart'; -// part 'user.g.dart'; +part 'user.g.dart'; @freezed class User with _$User { @@ -15,5 +15,5 @@ class User with _$User { bool? isOnline, }) = _User; - // factory User.fromJson(Map json) => _$UserFromJson(json); + factory User.fromJson(Map json) => _$UserFromJson(json); } diff --git a/client-mobile/lib/features/auth/domain/entities/user.freezed.dart b/client-mobile/lib/features/auth/domain/entities/user.freezed.dart index d81a2ee..1eab47a 100644 --- a/client-mobile/lib/features/auth/domain/entities/user.freezed.dart +++ b/client-mobile/lib/features/auth/domain/entities/user.freezed.dart @@ -14,6 +14,10 @@ T _$identity(T value) => value; final _privateConstructorUsedError = UnsupportedError( 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); +User _$UserFromJson(Map json) { + return _User.fromJson(json); +} + /// @nodoc mixin _$User { String get id => throw _privateConstructorUsedError; @@ -24,6 +28,7 @@ mixin _$User { DateTime? get lastSeen => throw _privateConstructorUsedError; bool? get isOnline => throw _privateConstructorUsedError; + Map toJson() => throw _privateConstructorUsedError; @JsonKey(ignore: true) $UserCopyWith get copyWith => throw _privateConstructorUsedError; } @@ -166,7 +171,7 @@ class __$$UserImplCopyWithImpl<$Res> } /// @nodoc - +@JsonSerializable() class _$UserImpl implements _User { const _$UserImpl( {required this.id, @@ -177,6 +182,9 @@ class _$UserImpl implements _User { this.lastSeen, this.isOnline}); + factory _$UserImpl.fromJson(Map json) => + _$$UserImplFromJson(json); + @override final String id; @override @@ -215,6 +223,7 @@ class _$UserImpl implements _User { other.isOnline == isOnline)); } + @JsonKey(ignore: true) @override int get hashCode => Object.hash( runtimeType, id, email, name, avatarUrl, phoneNumber, lastSeen, isOnline); @@ -224,6 +233,13 @@ class _$UserImpl implements _User { @pragma('vm:prefer-inline') _$$UserImplCopyWith<_$UserImpl> get copyWith => __$$UserImplCopyWithImpl<_$UserImpl>(this, _$identity); + + @override + Map toJson() { + return _$$UserImplToJson( + this, + ); + } } abstract class _User implements User { @@ -236,6 +252,8 @@ abstract class _User implements User { final DateTime? lastSeen, final bool? isOnline}) = _$UserImpl; + factory _User.fromJson(Map json) = _$UserImpl.fromJson; + @override String get id; @override diff --git a/client-mobile/lib/features/auth/domain/entities/user.g.dart b/client-mobile/lib/features/auth/domain/entities/user.g.dart new file mode 100644 index 0000000..f52bcec --- /dev/null +++ b/client-mobile/lib/features/auth/domain/entities/user.g.dart @@ -0,0 +1,30 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'user.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_$UserImpl _$$UserImplFromJson(Map json) => _$UserImpl( + id: json['id'] as String, + email: json['email'] as String, + name: json['name'] as String, + avatarUrl: json['avatarUrl'] as String?, + phoneNumber: json['phoneNumber'] as String?, + lastSeen: json['lastSeen'] == null + ? null + : DateTime.parse(json['lastSeen'] as String), + isOnline: json['isOnline'] as bool?, + ); + +Map _$$UserImplToJson(_$UserImpl instance) => + { + 'id': instance.id, + 'email': instance.email, + 'name': instance.name, + 'avatarUrl': instance.avatarUrl, + 'phoneNumber': instance.phoneNumber, + 'lastSeen': instance.lastSeen?.toIso8601String(), + 'isOnline': instance.isOnline, + }; diff --git a/client-mobile/lib/features/auth/domain/repositories/auth_repository.dart b/client-mobile/lib/features/auth/domain/repositories/auth_repository.dart index 6b32ebe..6dc6c33 100644 --- a/client-mobile/lib/features/auth/domain/repositories/auth_repository.dart +++ b/client-mobile/lib/features/auth/domain/repositories/auth_repository.dart @@ -2,8 +2,8 @@ import '../../../../core/errors/result.dart'; import '../entities/user.dart'; abstract class AuthRepository { - Future> login(String email, String password); - Future> register(String email, String password, String name); + Future> login(String username, String password); + Future> register(String username, String password, String name); Future> logout(); Future> getCurrentUser(); Future> refreshToken(); diff --git a/client-mobile/lib/features/auth/presentation/bloc/auth_bloc.dart b/client-mobile/lib/features/auth/presentation/bloc/auth_bloc.dart index 498183d..448528b 100644 --- a/client-mobile/lib/features/auth/presentation/bloc/auth_bloc.dart +++ b/client-mobile/lib/features/auth/presentation/bloc/auth_bloc.dart @@ -1,36 +1,59 @@ import 'package:flutter_bloc/flutter_bloc.dart'; +import '../../domain/repositories/auth_repository.dart'; import 'auth_event.dart'; import 'auth_state.dart'; class AuthBloc extends Bloc { - AuthBloc() : super(const AuthState.initial()) { + final AuthRepository authRepository; + + AuthBloc({required this.authRepository}) : super(const AuthState.initial()) { on(_onStarted); on(_onLoginRequested); on(_onRegisterRequested); on(_onLogoutRequested); on(_onAuthChecked); - on(_onEmailChanged); + on(_onUsernameChanged); on(_onPasswordChanged); on(_onNameChanged); } - Future _onStarted(AuthEventStarted event, emit) async {} - - Future _onLoginRequested(AuthEventLoginRequested event, emit) async { - emit(const AuthState.loading()); - emit(const AuthState.authenticated('user_123')); + Future _onStarted(AuthEventStarted event, Emitter emit) async { + add(const AuthEvent.authChecked()); } - Future _onRegisterRequested(AuthEventRegisterRequested event, emit) async { + Future _onLoginRequested(AuthEventLoginRequested event, Emitter emit) async { emit(const AuthState.loading()); + final result = await authRepository.login(event.username, event.password); + result.fold( + (error) => emit(AuthState.error('loginFailed')), + (user) => emit(AuthState.authenticated(user.id)), + ); } - Future _onLogoutRequested(AuthEventLogoutRequested event, emit) async { + Future _onRegisterRequested(AuthEventRegisterRequested event, Emitter emit) async { + emit(const AuthState.loading()); + final result = await authRepository.register(event.username, event.password, event.name); + result.fold( + (error) => emit(AuthState.error('registrationFailed')), + (user) => emit(AuthState.authenticated(user.id)), + ); + } + + Future _onLogoutRequested(AuthEventLogoutRequested event, Emitter emit) async { + emit(const AuthState.loading()); + await authRepository.logout(); emit(const AuthState.unauthenticated()); } - Future _onAuthChecked(AuthEventAuthChecked event, emit) async {} - void _onEmailChanged(AuthEventEmailChanged event, emit) {} - void _onPasswordChanged(AuthEventPasswordChanged event, emit) {} - void _onNameChanged(AuthEventNameChanged event, emit) {} + Future _onAuthChecked(AuthEventAuthChecked event, Emitter emit) async { + final result = await authRepository.getCurrentUser(); + result.fold( + (error) => emit(const AuthState.unauthenticated()), + (user) => emit(AuthState.authenticated(user.id)), + ); + } + + void _onUsernameChanged(AuthEventUsernameChanged event, Emitter emit) {} + void _onPasswordChanged(AuthEventPasswordChanged event, Emitter emit) {} + void _onNameChanged(AuthEventNameChanged event, Emitter emit) {} } diff --git a/client-mobile/lib/features/auth/presentation/bloc/auth_event.dart b/client-mobile/lib/features/auth/presentation/bloc/auth_event.dart index 7c46efc..8d88487 100644 --- a/client-mobile/lib/features/auth/presentation/bloc/auth_event.dart +++ b/client-mobile/lib/features/auth/presentation/bloc/auth_event.dart @@ -5,11 +5,11 @@ part 'auth_event.freezed.dart'; @freezed class AuthEvent with _$AuthEvent { const factory AuthEvent.started() = AuthEventStarted; - const factory AuthEvent.loginRequested(String email, String password) = AuthEventLoginRequested; - const factory AuthEvent.registerRequested(String email, String password, String name) = AuthEventRegisterRequested; + const factory AuthEvent.loginRequested(String username, String password) = AuthEventLoginRequested; + const factory AuthEvent.registerRequested(String username, String password, String name) = AuthEventRegisterRequested; const factory AuthEvent.logoutRequested() = AuthEventLogoutRequested; const factory AuthEvent.authChecked() = AuthEventAuthChecked; - const factory AuthEvent.emailChanged(String email) = AuthEventEmailChanged; + const factory AuthEvent.usernameChanged(String username) = AuthEventUsernameChanged; const factory AuthEvent.passwordChanged(String password) = AuthEventPasswordChanged; const factory AuthEvent.nameChanged(String name) = AuthEventNameChanged; } diff --git a/client-mobile/lib/features/auth/presentation/bloc/auth_event.freezed.dart b/client-mobile/lib/features/auth/presentation/bloc/auth_event.freezed.dart index e936ce4..ea438dc 100644 --- a/client-mobile/lib/features/auth/presentation/bloc/auth_event.freezed.dart +++ b/client-mobile/lib/features/auth/presentation/bloc/auth_event.freezed.dart @@ -19,12 +19,12 @@ mixin _$AuthEvent { @optionalTypeArgs TResult when({ required TResult Function() started, - required TResult Function(String email, String password) loginRequested, - required TResult Function(String email, String password, String name) + required TResult Function(String username, String password) loginRequested, + required TResult Function(String username, String password, String name) registerRequested, required TResult Function() logoutRequested, required TResult Function() authChecked, - required TResult Function(String email) emailChanged, + required TResult Function(String username) usernameChanged, required TResult Function(String password) passwordChanged, required TResult Function(String name) nameChanged, }) => @@ -32,12 +32,12 @@ mixin _$AuthEvent { @optionalTypeArgs TResult? whenOrNull({ TResult? Function()? started, - TResult? Function(String email, String password)? loginRequested, - TResult? Function(String email, String password, String name)? + TResult? Function(String username, String password)? loginRequested, + TResult? Function(String username, String password, String name)? registerRequested, TResult? Function()? logoutRequested, TResult? Function()? authChecked, - TResult? Function(String email)? emailChanged, + TResult? Function(String username)? usernameChanged, TResult? Function(String password)? passwordChanged, TResult? Function(String name)? nameChanged, }) => @@ -45,12 +45,12 @@ mixin _$AuthEvent { @optionalTypeArgs TResult maybeWhen({ TResult Function()? started, - TResult Function(String email, String password)? loginRequested, - TResult Function(String email, String password, String name)? + TResult Function(String username, String password)? loginRequested, + TResult Function(String username, String password, String name)? registerRequested, TResult Function()? logoutRequested, TResult Function()? authChecked, - TResult Function(String email)? emailChanged, + TResult Function(String username)? usernameChanged, TResult Function(String password)? passwordChanged, TResult Function(String name)? nameChanged, required TResult orElse(), @@ -64,7 +64,7 @@ mixin _$AuthEvent { registerRequested, required TResult Function(AuthEventLogoutRequested value) logoutRequested, required TResult Function(AuthEventAuthChecked value) authChecked, - required TResult Function(AuthEventEmailChanged value) emailChanged, + required TResult Function(AuthEventUsernameChanged value) usernameChanged, required TResult Function(AuthEventPasswordChanged value) passwordChanged, required TResult Function(AuthEventNameChanged value) nameChanged, }) => @@ -76,7 +76,7 @@ mixin _$AuthEvent { TResult? Function(AuthEventRegisterRequested value)? registerRequested, TResult? Function(AuthEventLogoutRequested value)? logoutRequested, TResult? Function(AuthEventAuthChecked value)? authChecked, - TResult? Function(AuthEventEmailChanged value)? emailChanged, + TResult? Function(AuthEventUsernameChanged value)? usernameChanged, TResult? Function(AuthEventPasswordChanged value)? passwordChanged, TResult? Function(AuthEventNameChanged value)? nameChanged, }) => @@ -88,7 +88,7 @@ mixin _$AuthEvent { TResult Function(AuthEventRegisterRequested value)? registerRequested, TResult Function(AuthEventLogoutRequested value)? logoutRequested, TResult Function(AuthEventAuthChecked value)? authChecked, - TResult Function(AuthEventEmailChanged value)? emailChanged, + TResult Function(AuthEventUsernameChanged value)? usernameChanged, TResult Function(AuthEventPasswordChanged value)? passwordChanged, TResult Function(AuthEventNameChanged value)? nameChanged, required TResult orElse(), @@ -152,12 +152,12 @@ class _$AuthEventStartedImpl implements AuthEventStarted { @optionalTypeArgs TResult when({ required TResult Function() started, - required TResult Function(String email, String password) loginRequested, - required TResult Function(String email, String password, String name) + required TResult Function(String username, String password) loginRequested, + required TResult Function(String username, String password, String name) registerRequested, required TResult Function() logoutRequested, required TResult Function() authChecked, - required TResult Function(String email) emailChanged, + required TResult Function(String username) usernameChanged, required TResult Function(String password) passwordChanged, required TResult Function(String name) nameChanged, }) { @@ -168,12 +168,12 @@ class _$AuthEventStartedImpl implements AuthEventStarted { @optionalTypeArgs TResult? whenOrNull({ TResult? Function()? started, - TResult? Function(String email, String password)? loginRequested, - TResult? Function(String email, String password, String name)? + TResult? Function(String username, String password)? loginRequested, + TResult? Function(String username, String password, String name)? registerRequested, TResult? Function()? logoutRequested, TResult? Function()? authChecked, - TResult? Function(String email)? emailChanged, + TResult? Function(String username)? usernameChanged, TResult? Function(String password)? passwordChanged, TResult? Function(String name)? nameChanged, }) { @@ -184,12 +184,12 @@ class _$AuthEventStartedImpl implements AuthEventStarted { @optionalTypeArgs TResult maybeWhen({ TResult Function()? started, - TResult Function(String email, String password)? loginRequested, - TResult Function(String email, String password, String name)? + TResult Function(String username, String password)? loginRequested, + TResult Function(String username, String password, String name)? registerRequested, TResult Function()? logoutRequested, TResult Function()? authChecked, - TResult Function(String email)? emailChanged, + TResult Function(String username)? usernameChanged, TResult Function(String password)? passwordChanged, TResult Function(String name)? nameChanged, required TResult orElse(), @@ -209,7 +209,7 @@ class _$AuthEventStartedImpl implements AuthEventStarted { registerRequested, required TResult Function(AuthEventLogoutRequested value) logoutRequested, required TResult Function(AuthEventAuthChecked value) authChecked, - required TResult Function(AuthEventEmailChanged value) emailChanged, + required TResult Function(AuthEventUsernameChanged value) usernameChanged, required TResult Function(AuthEventPasswordChanged value) passwordChanged, required TResult Function(AuthEventNameChanged value) nameChanged, }) { @@ -224,7 +224,7 @@ class _$AuthEventStartedImpl implements AuthEventStarted { TResult? Function(AuthEventRegisterRequested value)? registerRequested, TResult? Function(AuthEventLogoutRequested value)? logoutRequested, TResult? Function(AuthEventAuthChecked value)? authChecked, - TResult? Function(AuthEventEmailChanged value)? emailChanged, + TResult? Function(AuthEventUsernameChanged value)? usernameChanged, TResult? Function(AuthEventPasswordChanged value)? passwordChanged, TResult? Function(AuthEventNameChanged value)? nameChanged, }) { @@ -239,7 +239,7 @@ class _$AuthEventStartedImpl implements AuthEventStarted { TResult Function(AuthEventRegisterRequested value)? registerRequested, TResult Function(AuthEventLogoutRequested value)? logoutRequested, TResult Function(AuthEventAuthChecked value)? authChecked, - TResult Function(AuthEventEmailChanged value)? emailChanged, + TResult Function(AuthEventUsernameChanged value)? usernameChanged, TResult Function(AuthEventPasswordChanged value)? passwordChanged, TResult Function(AuthEventNameChanged value)? nameChanged, required TResult orElse(), @@ -262,7 +262,7 @@ abstract class _$$AuthEventLoginRequestedImplCopyWith<$Res> { $Res Function(_$AuthEventLoginRequestedImpl) then) = __$$AuthEventLoginRequestedImplCopyWithImpl<$Res>; @useResult - $Res call({String email, String password}); + $Res call({String username, String password}); } /// @nodoc @@ -277,13 +277,13 @@ class __$$AuthEventLoginRequestedImplCopyWithImpl<$Res> @pragma('vm:prefer-inline') @override $Res call({ - Object? email = null, + Object? username = null, Object? password = null, }) { return _then(_$AuthEventLoginRequestedImpl( - null == email - ? _value.email - : email // ignore: cast_nullable_to_non_nullable + null == username + ? _value.username + : username // ignore: cast_nullable_to_non_nullable as String, null == password ? _value.password @@ -296,16 +296,16 @@ class __$$AuthEventLoginRequestedImplCopyWithImpl<$Res> /// @nodoc class _$AuthEventLoginRequestedImpl implements AuthEventLoginRequested { - const _$AuthEventLoginRequestedImpl(this.email, this.password); + const _$AuthEventLoginRequestedImpl(this.username, this.password); @override - final String email; + final String username; @override final String password; @override String toString() { - return 'AuthEvent.loginRequested(email: $email, password: $password)'; + return 'AuthEvent.loginRequested(username: $username, password: $password)'; } @override @@ -313,13 +313,14 @@ class _$AuthEventLoginRequestedImpl implements AuthEventLoginRequested { return identical(this, other) || (other.runtimeType == runtimeType && other is _$AuthEventLoginRequestedImpl && - (identical(other.email, email) || other.email == email) && + (identical(other.username, username) || + other.username == username) && (identical(other.password, password) || other.password == password)); } @override - int get hashCode => Object.hash(runtimeType, email, password); + int get hashCode => Object.hash(runtimeType, username, password); @JsonKey(ignore: true) @override @@ -332,50 +333,50 @@ class _$AuthEventLoginRequestedImpl implements AuthEventLoginRequested { @optionalTypeArgs TResult when({ required TResult Function() started, - required TResult Function(String email, String password) loginRequested, - required TResult Function(String email, String password, String name) + required TResult Function(String username, String password) loginRequested, + required TResult Function(String username, String password, String name) registerRequested, required TResult Function() logoutRequested, required TResult Function() authChecked, - required TResult Function(String email) emailChanged, + required TResult Function(String username) usernameChanged, required TResult Function(String password) passwordChanged, required TResult Function(String name) nameChanged, }) { - return loginRequested(email, password); + return loginRequested(username, password); } @override @optionalTypeArgs TResult? whenOrNull({ TResult? Function()? started, - TResult? Function(String email, String password)? loginRequested, - TResult? Function(String email, String password, String name)? + TResult? Function(String username, String password)? loginRequested, + TResult? Function(String username, String password, String name)? registerRequested, TResult? Function()? logoutRequested, TResult? Function()? authChecked, - TResult? Function(String email)? emailChanged, + TResult? Function(String username)? usernameChanged, TResult? Function(String password)? passwordChanged, TResult? Function(String name)? nameChanged, }) { - return loginRequested?.call(email, password); + return loginRequested?.call(username, password); } @override @optionalTypeArgs TResult maybeWhen({ TResult Function()? started, - TResult Function(String email, String password)? loginRequested, - TResult Function(String email, String password, String name)? + TResult Function(String username, String password)? loginRequested, + TResult Function(String username, String password, String name)? registerRequested, TResult Function()? logoutRequested, TResult Function()? authChecked, - TResult Function(String email)? emailChanged, + TResult Function(String username)? usernameChanged, TResult Function(String password)? passwordChanged, TResult Function(String name)? nameChanged, required TResult orElse(), }) { if (loginRequested != null) { - return loginRequested(email, password); + return loginRequested(username, password); } return orElse(); } @@ -389,7 +390,7 @@ class _$AuthEventLoginRequestedImpl implements AuthEventLoginRequested { registerRequested, required TResult Function(AuthEventLogoutRequested value) logoutRequested, required TResult Function(AuthEventAuthChecked value) authChecked, - required TResult Function(AuthEventEmailChanged value) emailChanged, + required TResult Function(AuthEventUsernameChanged value) usernameChanged, required TResult Function(AuthEventPasswordChanged value) passwordChanged, required TResult Function(AuthEventNameChanged value) nameChanged, }) { @@ -404,7 +405,7 @@ class _$AuthEventLoginRequestedImpl implements AuthEventLoginRequested { TResult? Function(AuthEventRegisterRequested value)? registerRequested, TResult? Function(AuthEventLogoutRequested value)? logoutRequested, TResult? Function(AuthEventAuthChecked value)? authChecked, - TResult? Function(AuthEventEmailChanged value)? emailChanged, + TResult? Function(AuthEventUsernameChanged value)? usernameChanged, TResult? Function(AuthEventPasswordChanged value)? passwordChanged, TResult? Function(AuthEventNameChanged value)? nameChanged, }) { @@ -419,7 +420,7 @@ class _$AuthEventLoginRequestedImpl implements AuthEventLoginRequested { TResult Function(AuthEventRegisterRequested value)? registerRequested, TResult Function(AuthEventLogoutRequested value)? logoutRequested, TResult Function(AuthEventAuthChecked value)? authChecked, - TResult Function(AuthEventEmailChanged value)? emailChanged, + TResult Function(AuthEventUsernameChanged value)? usernameChanged, TResult Function(AuthEventPasswordChanged value)? passwordChanged, TResult Function(AuthEventNameChanged value)? nameChanged, required TResult orElse(), @@ -433,10 +434,10 @@ class _$AuthEventLoginRequestedImpl implements AuthEventLoginRequested { abstract class AuthEventLoginRequested implements AuthEvent { const factory AuthEventLoginRequested( - final String email, final String password) = + final String username, final String password) = _$AuthEventLoginRequestedImpl; - String get email; + String get username; String get password; @JsonKey(ignore: true) _$$AuthEventLoginRequestedImplCopyWith<_$AuthEventLoginRequestedImpl> @@ -450,7 +451,7 @@ abstract class _$$AuthEventRegisterRequestedImplCopyWith<$Res> { $Res Function(_$AuthEventRegisterRequestedImpl) then) = __$$AuthEventRegisterRequestedImplCopyWithImpl<$Res>; @useResult - $Res call({String email, String password, String name}); + $Res call({String username, String password, String name}); } /// @nodoc @@ -465,14 +466,14 @@ class __$$AuthEventRegisterRequestedImplCopyWithImpl<$Res> @pragma('vm:prefer-inline') @override $Res call({ - Object? email = null, + Object? username = null, Object? password = null, Object? name = null, }) { return _then(_$AuthEventRegisterRequestedImpl( - null == email - ? _value.email - : email // ignore: cast_nullable_to_non_nullable + null == username + ? _value.username + : username // ignore: cast_nullable_to_non_nullable as String, null == password ? _value.password @@ -489,10 +490,11 @@ class __$$AuthEventRegisterRequestedImplCopyWithImpl<$Res> /// @nodoc class _$AuthEventRegisterRequestedImpl implements AuthEventRegisterRequested { - const _$AuthEventRegisterRequestedImpl(this.email, this.password, this.name); + const _$AuthEventRegisterRequestedImpl( + this.username, this.password, this.name); @override - final String email; + final String username; @override final String password; @override @@ -500,7 +502,7 @@ class _$AuthEventRegisterRequestedImpl implements AuthEventRegisterRequested { @override String toString() { - return 'AuthEvent.registerRequested(email: $email, password: $password, name: $name)'; + return 'AuthEvent.registerRequested(username: $username, password: $password, name: $name)'; } @override @@ -508,14 +510,15 @@ class _$AuthEventRegisterRequestedImpl implements AuthEventRegisterRequested { return identical(this, other) || (other.runtimeType == runtimeType && other is _$AuthEventRegisterRequestedImpl && - (identical(other.email, email) || other.email == email) && + (identical(other.username, username) || + other.username == username) && (identical(other.password, password) || other.password == password) && (identical(other.name, name) || other.name == name)); } @override - int get hashCode => Object.hash(runtimeType, email, password, name); + int get hashCode => Object.hash(runtimeType, username, password, name); @JsonKey(ignore: true) @override @@ -528,50 +531,50 @@ class _$AuthEventRegisterRequestedImpl implements AuthEventRegisterRequested { @optionalTypeArgs TResult when({ required TResult Function() started, - required TResult Function(String email, String password) loginRequested, - required TResult Function(String email, String password, String name) + required TResult Function(String username, String password) loginRequested, + required TResult Function(String username, String password, String name) registerRequested, required TResult Function() logoutRequested, required TResult Function() authChecked, - required TResult Function(String email) emailChanged, + required TResult Function(String username) usernameChanged, required TResult Function(String password) passwordChanged, required TResult Function(String name) nameChanged, }) { - return registerRequested(email, password, name); + return registerRequested(username, password, name); } @override @optionalTypeArgs TResult? whenOrNull({ TResult? Function()? started, - TResult? Function(String email, String password)? loginRequested, - TResult? Function(String email, String password, String name)? + TResult? Function(String username, String password)? loginRequested, + TResult? Function(String username, String password, String name)? registerRequested, TResult? Function()? logoutRequested, TResult? Function()? authChecked, - TResult? Function(String email)? emailChanged, + TResult? Function(String username)? usernameChanged, TResult? Function(String password)? passwordChanged, TResult? Function(String name)? nameChanged, }) { - return registerRequested?.call(email, password, name); + return registerRequested?.call(username, password, name); } @override @optionalTypeArgs TResult maybeWhen({ TResult Function()? started, - TResult Function(String email, String password)? loginRequested, - TResult Function(String email, String password, String name)? + TResult Function(String username, String password)? loginRequested, + TResult Function(String username, String password, String name)? registerRequested, TResult Function()? logoutRequested, TResult Function()? authChecked, - TResult Function(String email)? emailChanged, + TResult Function(String username)? usernameChanged, TResult Function(String password)? passwordChanged, TResult Function(String name)? nameChanged, required TResult orElse(), }) { if (registerRequested != null) { - return registerRequested(email, password, name); + return registerRequested(username, password, name); } return orElse(); } @@ -585,7 +588,7 @@ class _$AuthEventRegisterRequestedImpl implements AuthEventRegisterRequested { registerRequested, required TResult Function(AuthEventLogoutRequested value) logoutRequested, required TResult Function(AuthEventAuthChecked value) authChecked, - required TResult Function(AuthEventEmailChanged value) emailChanged, + required TResult Function(AuthEventUsernameChanged value) usernameChanged, required TResult Function(AuthEventPasswordChanged value) passwordChanged, required TResult Function(AuthEventNameChanged value) nameChanged, }) { @@ -600,7 +603,7 @@ class _$AuthEventRegisterRequestedImpl implements AuthEventRegisterRequested { TResult? Function(AuthEventRegisterRequested value)? registerRequested, TResult? Function(AuthEventLogoutRequested value)? logoutRequested, TResult? Function(AuthEventAuthChecked value)? authChecked, - TResult? Function(AuthEventEmailChanged value)? emailChanged, + TResult? Function(AuthEventUsernameChanged value)? usernameChanged, TResult? Function(AuthEventPasswordChanged value)? passwordChanged, TResult? Function(AuthEventNameChanged value)? nameChanged, }) { @@ -615,7 +618,7 @@ class _$AuthEventRegisterRequestedImpl implements AuthEventRegisterRequested { TResult Function(AuthEventRegisterRequested value)? registerRequested, TResult Function(AuthEventLogoutRequested value)? logoutRequested, TResult Function(AuthEventAuthChecked value)? authChecked, - TResult Function(AuthEventEmailChanged value)? emailChanged, + TResult Function(AuthEventUsernameChanged value)? usernameChanged, TResult Function(AuthEventPasswordChanged value)? passwordChanged, TResult Function(AuthEventNameChanged value)? nameChanged, required TResult orElse(), @@ -629,10 +632,10 @@ class _$AuthEventRegisterRequestedImpl implements AuthEventRegisterRequested { abstract class AuthEventRegisterRequested implements AuthEvent { const factory AuthEventRegisterRequested( - final String email, final String password, final String name) = + final String username, final String password, final String name) = _$AuthEventRegisterRequestedImpl; - String get email; + String get username; String get password; String get name; @JsonKey(ignore: true) @@ -682,12 +685,12 @@ class _$AuthEventLogoutRequestedImpl implements AuthEventLogoutRequested { @optionalTypeArgs TResult when({ required TResult Function() started, - required TResult Function(String email, String password) loginRequested, - required TResult Function(String email, String password, String name) + required TResult Function(String username, String password) loginRequested, + required TResult Function(String username, String password, String name) registerRequested, required TResult Function() logoutRequested, required TResult Function() authChecked, - required TResult Function(String email) emailChanged, + required TResult Function(String username) usernameChanged, required TResult Function(String password) passwordChanged, required TResult Function(String name) nameChanged, }) { @@ -698,12 +701,12 @@ class _$AuthEventLogoutRequestedImpl implements AuthEventLogoutRequested { @optionalTypeArgs TResult? whenOrNull({ TResult? Function()? started, - TResult? Function(String email, String password)? loginRequested, - TResult? Function(String email, String password, String name)? + TResult? Function(String username, String password)? loginRequested, + TResult? Function(String username, String password, String name)? registerRequested, TResult? Function()? logoutRequested, TResult? Function()? authChecked, - TResult? Function(String email)? emailChanged, + TResult? Function(String username)? usernameChanged, TResult? Function(String password)? passwordChanged, TResult? Function(String name)? nameChanged, }) { @@ -714,12 +717,12 @@ class _$AuthEventLogoutRequestedImpl implements AuthEventLogoutRequested { @optionalTypeArgs TResult maybeWhen({ TResult Function()? started, - TResult Function(String email, String password)? loginRequested, - TResult Function(String email, String password, String name)? + TResult Function(String username, String password)? loginRequested, + TResult Function(String username, String password, String name)? registerRequested, TResult Function()? logoutRequested, TResult Function()? authChecked, - TResult Function(String email)? emailChanged, + TResult Function(String username)? usernameChanged, TResult Function(String password)? passwordChanged, TResult Function(String name)? nameChanged, required TResult orElse(), @@ -739,7 +742,7 @@ class _$AuthEventLogoutRequestedImpl implements AuthEventLogoutRequested { registerRequested, required TResult Function(AuthEventLogoutRequested value) logoutRequested, required TResult Function(AuthEventAuthChecked value) authChecked, - required TResult Function(AuthEventEmailChanged value) emailChanged, + required TResult Function(AuthEventUsernameChanged value) usernameChanged, required TResult Function(AuthEventPasswordChanged value) passwordChanged, required TResult Function(AuthEventNameChanged value) nameChanged, }) { @@ -754,7 +757,7 @@ class _$AuthEventLogoutRequestedImpl implements AuthEventLogoutRequested { TResult? Function(AuthEventRegisterRequested value)? registerRequested, TResult? Function(AuthEventLogoutRequested value)? logoutRequested, TResult? Function(AuthEventAuthChecked value)? authChecked, - TResult? Function(AuthEventEmailChanged value)? emailChanged, + TResult? Function(AuthEventUsernameChanged value)? usernameChanged, TResult? Function(AuthEventPasswordChanged value)? passwordChanged, TResult? Function(AuthEventNameChanged value)? nameChanged, }) { @@ -769,7 +772,7 @@ class _$AuthEventLogoutRequestedImpl implements AuthEventLogoutRequested { TResult Function(AuthEventRegisterRequested value)? registerRequested, TResult Function(AuthEventLogoutRequested value)? logoutRequested, TResult Function(AuthEventAuthChecked value)? authChecked, - TResult Function(AuthEventEmailChanged value)? emailChanged, + TResult Function(AuthEventUsernameChanged value)? usernameChanged, TResult Function(AuthEventPasswordChanged value)? passwordChanged, TResult Function(AuthEventNameChanged value)? nameChanged, required TResult orElse(), @@ -825,12 +828,12 @@ class _$AuthEventAuthCheckedImpl implements AuthEventAuthChecked { @optionalTypeArgs TResult when({ required TResult Function() started, - required TResult Function(String email, String password) loginRequested, - required TResult Function(String email, String password, String name) + required TResult Function(String username, String password) loginRequested, + required TResult Function(String username, String password, String name) registerRequested, required TResult Function() logoutRequested, required TResult Function() authChecked, - required TResult Function(String email) emailChanged, + required TResult Function(String username) usernameChanged, required TResult Function(String password) passwordChanged, required TResult Function(String name) nameChanged, }) { @@ -841,12 +844,12 @@ class _$AuthEventAuthCheckedImpl implements AuthEventAuthChecked { @optionalTypeArgs TResult? whenOrNull({ TResult? Function()? started, - TResult? Function(String email, String password)? loginRequested, - TResult? Function(String email, String password, String name)? + TResult? Function(String username, String password)? loginRequested, + TResult? Function(String username, String password, String name)? registerRequested, TResult? Function()? logoutRequested, TResult? Function()? authChecked, - TResult? Function(String email)? emailChanged, + TResult? Function(String username)? usernameChanged, TResult? Function(String password)? passwordChanged, TResult? Function(String name)? nameChanged, }) { @@ -857,12 +860,12 @@ class _$AuthEventAuthCheckedImpl implements AuthEventAuthChecked { @optionalTypeArgs TResult maybeWhen({ TResult Function()? started, - TResult Function(String email, String password)? loginRequested, - TResult Function(String email, String password, String name)? + TResult Function(String username, String password)? loginRequested, + TResult Function(String username, String password, String name)? registerRequested, TResult Function()? logoutRequested, TResult Function()? authChecked, - TResult Function(String email)? emailChanged, + TResult Function(String username)? usernameChanged, TResult Function(String password)? passwordChanged, TResult Function(String name)? nameChanged, required TResult orElse(), @@ -882,7 +885,7 @@ class _$AuthEventAuthCheckedImpl implements AuthEventAuthChecked { registerRequested, required TResult Function(AuthEventLogoutRequested value) logoutRequested, required TResult Function(AuthEventAuthChecked value) authChecked, - required TResult Function(AuthEventEmailChanged value) emailChanged, + required TResult Function(AuthEventUsernameChanged value) usernameChanged, required TResult Function(AuthEventPasswordChanged value) passwordChanged, required TResult Function(AuthEventNameChanged value) nameChanged, }) { @@ -897,7 +900,7 @@ class _$AuthEventAuthCheckedImpl implements AuthEventAuthChecked { TResult? Function(AuthEventRegisterRequested value)? registerRequested, TResult? Function(AuthEventLogoutRequested value)? logoutRequested, TResult? Function(AuthEventAuthChecked value)? authChecked, - TResult? Function(AuthEventEmailChanged value)? emailChanged, + TResult? Function(AuthEventUsernameChanged value)? usernameChanged, TResult? Function(AuthEventPasswordChanged value)? passwordChanged, TResult? Function(AuthEventNameChanged value)? nameChanged, }) { @@ -912,7 +915,7 @@ class _$AuthEventAuthCheckedImpl implements AuthEventAuthChecked { TResult Function(AuthEventRegisterRequested value)? registerRequested, TResult Function(AuthEventLogoutRequested value)? logoutRequested, TResult Function(AuthEventAuthChecked value)? authChecked, - TResult Function(AuthEventEmailChanged value)? emailChanged, + TResult Function(AuthEventUsernameChanged value)? usernameChanged, TResult Function(AuthEventPasswordChanged value)? passwordChanged, TResult Function(AuthEventNameChanged value)? nameChanged, required TResult orElse(), @@ -929,32 +932,33 @@ abstract class AuthEventAuthChecked implements AuthEvent { } /// @nodoc -abstract class _$$AuthEventEmailChangedImplCopyWith<$Res> { - factory _$$AuthEventEmailChangedImplCopyWith( - _$AuthEventEmailChangedImpl value, - $Res Function(_$AuthEventEmailChangedImpl) then) = - __$$AuthEventEmailChangedImplCopyWithImpl<$Res>; +abstract class _$$AuthEventUsernameChangedImplCopyWith<$Res> { + factory _$$AuthEventUsernameChangedImplCopyWith( + _$AuthEventUsernameChangedImpl value, + $Res Function(_$AuthEventUsernameChangedImpl) then) = + __$$AuthEventUsernameChangedImplCopyWithImpl<$Res>; @useResult - $Res call({String email}); + $Res call({String username}); } /// @nodoc -class __$$AuthEventEmailChangedImplCopyWithImpl<$Res> - extends _$AuthEventCopyWithImpl<$Res, _$AuthEventEmailChangedImpl> - implements _$$AuthEventEmailChangedImplCopyWith<$Res> { - __$$AuthEventEmailChangedImplCopyWithImpl(_$AuthEventEmailChangedImpl _value, - $Res Function(_$AuthEventEmailChangedImpl) _then) +class __$$AuthEventUsernameChangedImplCopyWithImpl<$Res> + extends _$AuthEventCopyWithImpl<$Res, _$AuthEventUsernameChangedImpl> + implements _$$AuthEventUsernameChangedImplCopyWith<$Res> { + __$$AuthEventUsernameChangedImplCopyWithImpl( + _$AuthEventUsernameChangedImpl _value, + $Res Function(_$AuthEventUsernameChangedImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @override $Res call({ - Object? email = null, + Object? username = null, }) { - return _then(_$AuthEventEmailChangedImpl( - null == email - ? _value.email - : email // ignore: cast_nullable_to_non_nullable + return _then(_$AuthEventUsernameChangedImpl( + null == username + ? _value.username + : username // ignore: cast_nullable_to_non_nullable as String, )); } @@ -962,83 +966,84 @@ class __$$AuthEventEmailChangedImplCopyWithImpl<$Res> /// @nodoc -class _$AuthEventEmailChangedImpl implements AuthEventEmailChanged { - const _$AuthEventEmailChangedImpl(this.email); +class _$AuthEventUsernameChangedImpl implements AuthEventUsernameChanged { + const _$AuthEventUsernameChangedImpl(this.username); @override - final String email; + final String username; @override String toString() { - return 'AuthEvent.emailChanged(email: $email)'; + return 'AuthEvent.usernameChanged(username: $username)'; } @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$AuthEventEmailChangedImpl && - (identical(other.email, email) || other.email == email)); + other is _$AuthEventUsernameChangedImpl && + (identical(other.username, username) || + other.username == username)); } @override - int get hashCode => Object.hash(runtimeType, email); + int get hashCode => Object.hash(runtimeType, username); @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$AuthEventEmailChangedImplCopyWith<_$AuthEventEmailChangedImpl> - get copyWith => __$$AuthEventEmailChangedImplCopyWithImpl< - _$AuthEventEmailChangedImpl>(this, _$identity); + _$$AuthEventUsernameChangedImplCopyWith<_$AuthEventUsernameChangedImpl> + get copyWith => __$$AuthEventUsernameChangedImplCopyWithImpl< + _$AuthEventUsernameChangedImpl>(this, _$identity); @override @optionalTypeArgs TResult when({ required TResult Function() started, - required TResult Function(String email, String password) loginRequested, - required TResult Function(String email, String password, String name) + required TResult Function(String username, String password) loginRequested, + required TResult Function(String username, String password, String name) registerRequested, required TResult Function() logoutRequested, required TResult Function() authChecked, - required TResult Function(String email) emailChanged, + required TResult Function(String username) usernameChanged, required TResult Function(String password) passwordChanged, required TResult Function(String name) nameChanged, }) { - return emailChanged(email); + return usernameChanged(username); } @override @optionalTypeArgs TResult? whenOrNull({ TResult? Function()? started, - TResult? Function(String email, String password)? loginRequested, - TResult? Function(String email, String password, String name)? + TResult? Function(String username, String password)? loginRequested, + TResult? Function(String username, String password, String name)? registerRequested, TResult? Function()? logoutRequested, TResult? Function()? authChecked, - TResult? Function(String email)? emailChanged, + TResult? Function(String username)? usernameChanged, TResult? Function(String password)? passwordChanged, TResult? Function(String name)? nameChanged, }) { - return emailChanged?.call(email); + return usernameChanged?.call(username); } @override @optionalTypeArgs TResult maybeWhen({ TResult Function()? started, - TResult Function(String email, String password)? loginRequested, - TResult Function(String email, String password, String name)? + TResult Function(String username, String password)? loginRequested, + TResult Function(String username, String password, String name)? registerRequested, TResult Function()? logoutRequested, TResult Function()? authChecked, - TResult Function(String email)? emailChanged, + TResult Function(String username)? usernameChanged, TResult Function(String password)? passwordChanged, TResult Function(String name)? nameChanged, required TResult orElse(), }) { - if (emailChanged != null) { - return emailChanged(email); + if (usernameChanged != null) { + return usernameChanged(username); } return orElse(); } @@ -1052,11 +1057,11 @@ class _$AuthEventEmailChangedImpl implements AuthEventEmailChanged { registerRequested, required TResult Function(AuthEventLogoutRequested value) logoutRequested, required TResult Function(AuthEventAuthChecked value) authChecked, - required TResult Function(AuthEventEmailChanged value) emailChanged, + required TResult Function(AuthEventUsernameChanged value) usernameChanged, required TResult Function(AuthEventPasswordChanged value) passwordChanged, required TResult Function(AuthEventNameChanged value) nameChanged, }) { - return emailChanged(this); + return usernameChanged(this); } @override @@ -1067,11 +1072,11 @@ class _$AuthEventEmailChangedImpl implements AuthEventEmailChanged { TResult? Function(AuthEventRegisterRequested value)? registerRequested, TResult? Function(AuthEventLogoutRequested value)? logoutRequested, TResult? Function(AuthEventAuthChecked value)? authChecked, - TResult? Function(AuthEventEmailChanged value)? emailChanged, + TResult? Function(AuthEventUsernameChanged value)? usernameChanged, TResult? Function(AuthEventPasswordChanged value)? passwordChanged, TResult? Function(AuthEventNameChanged value)? nameChanged, }) { - return emailChanged?.call(this); + return usernameChanged?.call(this); } @override @@ -1082,25 +1087,25 @@ class _$AuthEventEmailChangedImpl implements AuthEventEmailChanged { TResult Function(AuthEventRegisterRequested value)? registerRequested, TResult Function(AuthEventLogoutRequested value)? logoutRequested, TResult Function(AuthEventAuthChecked value)? authChecked, - TResult Function(AuthEventEmailChanged value)? emailChanged, + TResult Function(AuthEventUsernameChanged value)? usernameChanged, TResult Function(AuthEventPasswordChanged value)? passwordChanged, TResult Function(AuthEventNameChanged value)? nameChanged, required TResult orElse(), }) { - if (emailChanged != null) { - return emailChanged(this); + if (usernameChanged != null) { + return usernameChanged(this); } return orElse(); } } -abstract class AuthEventEmailChanged implements AuthEvent { - const factory AuthEventEmailChanged(final String email) = - _$AuthEventEmailChangedImpl; +abstract class AuthEventUsernameChanged implements AuthEvent { + const factory AuthEventUsernameChanged(final String username) = + _$AuthEventUsernameChangedImpl; - String get email; + String get username; @JsonKey(ignore: true) - _$$AuthEventEmailChangedImplCopyWith<_$AuthEventEmailChangedImpl> + _$$AuthEventUsernameChangedImplCopyWith<_$AuthEventUsernameChangedImpl> get copyWith => throw _privateConstructorUsedError; } @@ -1173,12 +1178,12 @@ class _$AuthEventPasswordChangedImpl implements AuthEventPasswordChanged { @optionalTypeArgs TResult when({ required TResult Function() started, - required TResult Function(String email, String password) loginRequested, - required TResult Function(String email, String password, String name) + required TResult Function(String username, String password) loginRequested, + required TResult Function(String username, String password, String name) registerRequested, required TResult Function() logoutRequested, required TResult Function() authChecked, - required TResult Function(String email) emailChanged, + required TResult Function(String username) usernameChanged, required TResult Function(String password) passwordChanged, required TResult Function(String name) nameChanged, }) { @@ -1189,12 +1194,12 @@ class _$AuthEventPasswordChangedImpl implements AuthEventPasswordChanged { @optionalTypeArgs TResult? whenOrNull({ TResult? Function()? started, - TResult? Function(String email, String password)? loginRequested, - TResult? Function(String email, String password, String name)? + TResult? Function(String username, String password)? loginRequested, + TResult? Function(String username, String password, String name)? registerRequested, TResult? Function()? logoutRequested, TResult? Function()? authChecked, - TResult? Function(String email)? emailChanged, + TResult? Function(String username)? usernameChanged, TResult? Function(String password)? passwordChanged, TResult? Function(String name)? nameChanged, }) { @@ -1205,12 +1210,12 @@ class _$AuthEventPasswordChangedImpl implements AuthEventPasswordChanged { @optionalTypeArgs TResult maybeWhen({ TResult Function()? started, - TResult Function(String email, String password)? loginRequested, - TResult Function(String email, String password, String name)? + TResult Function(String username, String password)? loginRequested, + TResult Function(String username, String password, String name)? registerRequested, TResult Function()? logoutRequested, TResult Function()? authChecked, - TResult Function(String email)? emailChanged, + TResult Function(String username)? usernameChanged, TResult Function(String password)? passwordChanged, TResult Function(String name)? nameChanged, required TResult orElse(), @@ -1230,7 +1235,7 @@ class _$AuthEventPasswordChangedImpl implements AuthEventPasswordChanged { registerRequested, required TResult Function(AuthEventLogoutRequested value) logoutRequested, required TResult Function(AuthEventAuthChecked value) authChecked, - required TResult Function(AuthEventEmailChanged value) emailChanged, + required TResult Function(AuthEventUsernameChanged value) usernameChanged, required TResult Function(AuthEventPasswordChanged value) passwordChanged, required TResult Function(AuthEventNameChanged value) nameChanged, }) { @@ -1245,7 +1250,7 @@ class _$AuthEventPasswordChangedImpl implements AuthEventPasswordChanged { TResult? Function(AuthEventRegisterRequested value)? registerRequested, TResult? Function(AuthEventLogoutRequested value)? logoutRequested, TResult? Function(AuthEventAuthChecked value)? authChecked, - TResult? Function(AuthEventEmailChanged value)? emailChanged, + TResult? Function(AuthEventUsernameChanged value)? usernameChanged, TResult? Function(AuthEventPasswordChanged value)? passwordChanged, TResult? Function(AuthEventNameChanged value)? nameChanged, }) { @@ -1260,7 +1265,7 @@ class _$AuthEventPasswordChangedImpl implements AuthEventPasswordChanged { TResult Function(AuthEventRegisterRequested value)? registerRequested, TResult Function(AuthEventLogoutRequested value)? logoutRequested, TResult Function(AuthEventAuthChecked value)? authChecked, - TResult Function(AuthEventEmailChanged value)? emailChanged, + TResult Function(AuthEventUsernameChanged value)? usernameChanged, TResult Function(AuthEventPasswordChanged value)? passwordChanged, TResult Function(AuthEventNameChanged value)? nameChanged, required TResult orElse(), @@ -1349,12 +1354,12 @@ class _$AuthEventNameChangedImpl implements AuthEventNameChanged { @optionalTypeArgs TResult when({ required TResult Function() started, - required TResult Function(String email, String password) loginRequested, - required TResult Function(String email, String password, String name) + required TResult Function(String username, String password) loginRequested, + required TResult Function(String username, String password, String name) registerRequested, required TResult Function() logoutRequested, required TResult Function() authChecked, - required TResult Function(String email) emailChanged, + required TResult Function(String username) usernameChanged, required TResult Function(String password) passwordChanged, required TResult Function(String name) nameChanged, }) { @@ -1365,12 +1370,12 @@ class _$AuthEventNameChangedImpl implements AuthEventNameChanged { @optionalTypeArgs TResult? whenOrNull({ TResult? Function()? started, - TResult? Function(String email, String password)? loginRequested, - TResult? Function(String email, String password, String name)? + TResult? Function(String username, String password)? loginRequested, + TResult? Function(String username, String password, String name)? registerRequested, TResult? Function()? logoutRequested, TResult? Function()? authChecked, - TResult? Function(String email)? emailChanged, + TResult? Function(String username)? usernameChanged, TResult? Function(String password)? passwordChanged, TResult? Function(String name)? nameChanged, }) { @@ -1381,12 +1386,12 @@ class _$AuthEventNameChangedImpl implements AuthEventNameChanged { @optionalTypeArgs TResult maybeWhen({ TResult Function()? started, - TResult Function(String email, String password)? loginRequested, - TResult Function(String email, String password, String name)? + TResult Function(String username, String password)? loginRequested, + TResult Function(String username, String password, String name)? registerRequested, TResult Function()? logoutRequested, TResult Function()? authChecked, - TResult Function(String email)? emailChanged, + TResult Function(String username)? usernameChanged, TResult Function(String password)? passwordChanged, TResult Function(String name)? nameChanged, required TResult orElse(), @@ -1406,7 +1411,7 @@ class _$AuthEventNameChangedImpl implements AuthEventNameChanged { registerRequested, required TResult Function(AuthEventLogoutRequested value) logoutRequested, required TResult Function(AuthEventAuthChecked value) authChecked, - required TResult Function(AuthEventEmailChanged value) emailChanged, + required TResult Function(AuthEventUsernameChanged value) usernameChanged, required TResult Function(AuthEventPasswordChanged value) passwordChanged, required TResult Function(AuthEventNameChanged value) nameChanged, }) { @@ -1421,7 +1426,7 @@ class _$AuthEventNameChangedImpl implements AuthEventNameChanged { TResult? Function(AuthEventRegisterRequested value)? registerRequested, TResult? Function(AuthEventLogoutRequested value)? logoutRequested, TResult? Function(AuthEventAuthChecked value)? authChecked, - TResult? Function(AuthEventEmailChanged value)? emailChanged, + TResult? Function(AuthEventUsernameChanged value)? usernameChanged, TResult? Function(AuthEventPasswordChanged value)? passwordChanged, TResult? Function(AuthEventNameChanged value)? nameChanged, }) { @@ -1436,7 +1441,7 @@ class _$AuthEventNameChangedImpl implements AuthEventNameChanged { TResult Function(AuthEventRegisterRequested value)? registerRequested, TResult Function(AuthEventLogoutRequested value)? logoutRequested, TResult Function(AuthEventAuthChecked value)? authChecked, - TResult Function(AuthEventEmailChanged value)? emailChanged, + TResult Function(AuthEventUsernameChanged value)? usernameChanged, TResult Function(AuthEventPasswordChanged value)? passwordChanged, TResult Function(AuthEventNameChanged value)? nameChanged, required TResult orElse(), diff --git a/client-mobile/lib/features/auth/presentation/pages/login_page.dart b/client-mobile/lib/features/auth/presentation/pages/login_page.dart index c9dc41f..358c587 100644 --- a/client-mobile/lib/features/auth/presentation/pages/login_page.dart +++ b/client-mobile/lib/features/auth/presentation/pages/login_page.dart @@ -1,8 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import '../bloc/auth_bloc.dart'; -import '../bloc/auth_event.dart'; -import '../bloc/auth_state.dart'; +import 'package:messenger_app/features/auth/presentation/bloc/auth_bloc.dart'; +import 'package:messenger_app/features/auth/presentation/bloc/auth_event.dart'; +import 'package:messenger_app/features/auth/presentation/bloc/auth_state.dart'; +import 'package:messenger_app/features/settings/presentation/bloc/settings_bloc.dart'; +import 'package:messenger_app/features/settings/presentation/bloc/settings_state.dart'; +import 'package:messenger_app/features/settings/presentation/pages/settings_page.dart'; +import 'package:messenger_app/l10n/app_localizations.dart'; class LoginPage extends StatefulWidget { const LoginPage({super.key}); @@ -25,25 +29,41 @@ class _LoginPageState extends State { @override Widget build(BuildContext context) { + final l10n = AppLocalizations.of(context)!; return Scaffold( appBar: AppBar( - title: const Text('Вход'), + title: Text(l10n.login), + actions: [ + IconButton( + icon: const Icon(Icons.settings), + onPressed: () { + Navigator.of(context).push( + MaterialPageRoute(builder: (_) => const SettingsPage()), + ); + }, + ), + ], ), body: BlocListener( listener: (context, state) { state.whenOrNull( authenticated: (userId) { - Navigator.of(context).popUntil((route) => route.isFirst); + // Navigation handled in app.dart home }, error: (message) { + final errorMessage = message == 'loginFailed' + ? l10n.loginFailed + : message == 'registrationFailed' + ? l10n.registrationFailed + : message; ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text(message)), + SnackBar(content: Text(errorMessage)), ); }, ); }, child: Center( - child: Padding( + child: SingleChildScrollView( padding: const EdgeInsets.all(24.0), child: Form( key: _formKey, @@ -56,20 +76,45 @@ class _LoginPageState extends State { size: 80, color: Color(0xFF2481CC), ), + const SizedBox(height: 16), + BlocBuilder( + builder: (context, state) { + final apiUrl = state.when( + initial: () => '', + loading: () => '', + loaded: (url, _, __, ___, ____) => url, + error: (_) => '', + ); + return Column( + children: [ + Text( + l10n.server, + style: const TextStyle(fontSize: 12, color: Colors.grey), + ), + Text( + apiUrl.isEmpty ? l10n.notSpecified : apiUrl, + style: const TextStyle(fontWeight: FontWeight.bold), + textAlign: TextAlign.center, + ), + ], + ); + }, + ), const SizedBox(height: 32), TextFormField( controller: _emailController, - decoration: const InputDecoration( - labelText: 'Email', - prefixIcon: Icon(Icons.email_outlined), + decoration: InputDecoration( + labelText: l10n.username, + prefixIcon: const Icon(Icons.person_outline), ), - keyboardType: TextInputType.emailAddress, + keyboardType: TextInputType.text, validator: (value) { if (value == null || value.isEmpty) { - return 'Введите email'; + return l10n.enterUsername; } - if (!value.contains('@')) { - return 'Введите корректный email'; + // Регулярка для проверки отсутствия кириллицы и минимум 3 символа + if (value.length < 3 || RegExp(r'[а-яА-ЯёЁ]').hasMatch(value)) { + return l10n.invalidUsername; } return null; }, @@ -77,9 +122,9 @@ class _LoginPageState extends State { const SizedBox(height: 16), TextFormField( controller: _passwordController, - decoration: const InputDecoration( - labelText: 'Пароль', - prefixIcon: Icon(Icons.lock_outlined), + decoration: InputDecoration( + labelText: l10n.password, + prefixIcon: const Icon(Icons.lock_outlined), ), obscureText: true, validator: (value) { @@ -94,34 +139,46 @@ class _LoginPageState extends State { ), const SizedBox(height: 32), BlocBuilder( - builder: (context, state) { - if (state is AuthLoading) { + builder: (context, authState) { + if (authState is AuthLoading) { return const Center(child: CircularProgressIndicator()); } return ElevatedButton( onPressed: () { if (_formKey.currentState?.validate() ?? false) { context.read().add( - AuthEvent.loginRequested( - _emailController.text, - _passwordController.text, - ), - ); + AuthEvent.loginRequested( + _emailController.text, + _passwordController.text, + ), + ); } }, - child: const Padding( - padding: EdgeInsets.symmetric(vertical: 12), - child: Text('Войти', style: TextStyle(fontSize: 16)), + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 12), + child: Text(l10n.loginButton, style: const TextStyle(fontSize: 16)), ), ); }, ), const SizedBox(height: 16), - TextButton( - onPressed: () { - // Navigate to register page + BlocBuilder( + builder: (context, settingsState) { + final isRegistrationEnabled = settingsState.when( + initial: () => false, + loading: () => false, + loaded: (_, config, __, ___, status) => + status == ConnectionStatus.connected && (config?.system.enableRegistration ?? false), + error: (_) => false, + ); + + return TextButton( + onPressed: isRegistrationEnabled ? () { + // Navigate to register page + } : null, + child: Text(l10n.noAccount), + ); }, - child: const Text('Нет аккаунта? Зарегистрироваться'), ), ], ), diff --git a/client-mobile/lib/features/settings/data/datasources/settings_remote_datasource.dart b/client-mobile/lib/features/settings/data/datasources/settings_remote_datasource.dart index 06bb9ad..d58f83b 100644 --- a/client-mobile/lib/features/settings/data/datasources/settings_remote_datasource.dart +++ b/client-mobile/lib/features/settings/data/datasources/settings_remote_datasource.dart @@ -15,6 +15,7 @@ class SettingsRemoteDataSourceImpl implements SettingsRemoteDataSource { @override Future> getServerConfig() async { try { + // Backend ожидает /api/config final response = await _dio.get('/api/config'); if (response.statusCode == 200) { final config = ServerConfig.fromJson(response.data as Map); @@ -23,8 +24,10 @@ class SettingsRemoteDataSourceImpl implements SettingsRemoteDataSource { return Result.failure(AppError.server(statusCode: 500, message: 'Failed to load config')); } on DioException catch (e) { return Result.failure(AppError.network(message: e.message)); + } on TypeError catch (e) { + return Result.failure(AppError.unknown(message: 'Data parsing error: ${e.toString()}')); } catch (e) { - return Result.failure(const AppError.unknown(message: 'Unknown error')); + return Result.failure(AppError.unknown(message: e.toString())); } } } diff --git a/client-mobile/lib/features/settings/domain/entities/server_config.dart b/client-mobile/lib/features/settings/domain/entities/server_config.dart index 1f16bcb..b9c0322 100644 --- a/client-mobile/lib/features/settings/domain/entities/server_config.dart +++ b/client-mobile/lib/features/settings/domain/entities/server_config.dart @@ -20,11 +20,13 @@ class ServerConfig with _$ServerConfig { _$ServerConfigFromJson(json); } -@Freezed(toJson: true) +@freezed class SystemConfig with _$SystemConfig { const factory SystemConfig({ required String domainUrl, required bool enableRegistration, + @Default('UTC') String serverTimezone, + @Default('admin') String adminRoute, }) = _SystemConfig; factory SystemConfig.fromJson(Map json) => @@ -54,6 +56,7 @@ class ChatsModuleConfig with _$ChatsModuleConfig { required int maxGroupParticipants, required bool allowChatToGroupConversion, required bool enableFolders, + @Default(false) bool enableAutoClean, }) = _ChatsModuleConfig; factory ChatsModuleConfig.fromJson(Map json) => @@ -78,6 +81,7 @@ class MessagesConfig with _$MessagesConfig { required bool allowLinks, required bool allowPolls, required bool allowPinning, + @Default(0) int maxFileSize, }) = _MessagesConfig; factory MessagesConfig.fromJson(Map json) => @@ -93,6 +97,8 @@ class WebRtcConfig with _$WebRtcConfig { required bool enableScreenSharing, required String turnHost, required int turnPort, + @Default('') String turnUser, + @Default('') String turnSecret, }) = _WebRtcConfig; factory WebRtcConfig.fromJson(Map json) => @@ -104,6 +110,7 @@ class KlipyConfig with _$KlipyConfig { const factory KlipyConfig({ required bool enabled, required String appName, + @Default('') String apiKey, }) = _KlipyConfig; factory KlipyConfig.fromJson(Map json) => @@ -113,7 +120,7 @@ class KlipyConfig with _$KlipyConfig { @Freezed(toJson: true) class ImportConfig with _$ImportConfig { const factory ImportConfig({ - required bool enabled, + @Default(false) bool enableTelegramImport, }) = _ImportConfig; factory ImportConfig.fromJson(Map json) => diff --git a/client-mobile/lib/features/settings/domain/entities/server_config.freezed.dart b/client-mobile/lib/features/settings/domain/entities/server_config.freezed.dart index 55b3713..47ed32a 100644 --- a/client-mobile/lib/features/settings/domain/entities/server_config.freezed.dart +++ b/client-mobile/lib/features/settings/domain/entities/server_config.freezed.dart @@ -395,6 +395,8 @@ SystemConfig _$SystemConfigFromJson(Map json) { mixin _$SystemConfig { String get domainUrl => throw _privateConstructorUsedError; bool get enableRegistration => throw _privateConstructorUsedError; + String get serverTimezone => throw _privateConstructorUsedError; + String get adminRoute => throw _privateConstructorUsedError; Map toJson() => throw _privateConstructorUsedError; @JsonKey(ignore: true) @@ -408,7 +410,11 @@ abstract class $SystemConfigCopyWith<$Res> { SystemConfig value, $Res Function(SystemConfig) then) = _$SystemConfigCopyWithImpl<$Res, SystemConfig>; @useResult - $Res call({String domainUrl, bool enableRegistration}); + $Res call( + {String domainUrl, + bool enableRegistration, + String serverTimezone, + String adminRoute}); } /// @nodoc @@ -426,6 +432,8 @@ class _$SystemConfigCopyWithImpl<$Res, $Val extends SystemConfig> $Res call({ Object? domainUrl = null, Object? enableRegistration = null, + Object? serverTimezone = null, + Object? adminRoute = null, }) { return _then(_value.copyWith( domainUrl: null == domainUrl @@ -436,6 +444,14 @@ class _$SystemConfigCopyWithImpl<$Res, $Val extends SystemConfig> ? _value.enableRegistration : enableRegistration // ignore: cast_nullable_to_non_nullable as bool, + serverTimezone: null == serverTimezone + ? _value.serverTimezone + : serverTimezone // ignore: cast_nullable_to_non_nullable + as String, + adminRoute: null == adminRoute + ? _value.adminRoute + : adminRoute // ignore: cast_nullable_to_non_nullable + as String, ) as $Val); } } @@ -448,7 +464,11 @@ abstract class _$$SystemConfigImplCopyWith<$Res> __$$SystemConfigImplCopyWithImpl<$Res>; @override @useResult - $Res call({String domainUrl, bool enableRegistration}); + $Res call( + {String domainUrl, + bool enableRegistration, + String serverTimezone, + String adminRoute}); } /// @nodoc @@ -464,6 +484,8 @@ class __$$SystemConfigImplCopyWithImpl<$Res> $Res call({ Object? domainUrl = null, Object? enableRegistration = null, + Object? serverTimezone = null, + Object? adminRoute = null, }) { return _then(_$SystemConfigImpl( domainUrl: null == domainUrl @@ -474,6 +496,14 @@ class __$$SystemConfigImplCopyWithImpl<$Res> ? _value.enableRegistration : enableRegistration // ignore: cast_nullable_to_non_nullable as bool, + serverTimezone: null == serverTimezone + ? _value.serverTimezone + : serverTimezone // ignore: cast_nullable_to_non_nullable + as String, + adminRoute: null == adminRoute + ? _value.adminRoute + : adminRoute // ignore: cast_nullable_to_non_nullable + as String, )); } } @@ -482,7 +512,10 @@ class __$$SystemConfigImplCopyWithImpl<$Res> @JsonSerializable() class _$SystemConfigImpl implements _SystemConfig { const _$SystemConfigImpl( - {required this.domainUrl, required this.enableRegistration}); + {required this.domainUrl, + required this.enableRegistration, + this.serverTimezone = 'UTC', + this.adminRoute = 'admin'}); factory _$SystemConfigImpl.fromJson(Map json) => _$$SystemConfigImplFromJson(json); @@ -491,10 +524,16 @@ class _$SystemConfigImpl implements _SystemConfig { final String domainUrl; @override final bool enableRegistration; + @override + @JsonKey() + final String serverTimezone; + @override + @JsonKey() + final String adminRoute; @override String toString() { - return 'SystemConfig(domainUrl: $domainUrl, enableRegistration: $enableRegistration)'; + return 'SystemConfig(domainUrl: $domainUrl, enableRegistration: $enableRegistration, serverTimezone: $serverTimezone, adminRoute: $adminRoute)'; } @override @@ -505,12 +544,17 @@ class _$SystemConfigImpl implements _SystemConfig { (identical(other.domainUrl, domainUrl) || other.domainUrl == domainUrl) && (identical(other.enableRegistration, enableRegistration) || - other.enableRegistration == enableRegistration)); + other.enableRegistration == enableRegistration) && + (identical(other.serverTimezone, serverTimezone) || + other.serverTimezone == serverTimezone) && + (identical(other.adminRoute, adminRoute) || + other.adminRoute == adminRoute)); } @JsonKey(ignore: true) @override - int get hashCode => Object.hash(runtimeType, domainUrl, enableRegistration); + int get hashCode => Object.hash( + runtimeType, domainUrl, enableRegistration, serverTimezone, adminRoute); @JsonKey(ignore: true) @override @@ -529,7 +573,9 @@ class _$SystemConfigImpl implements _SystemConfig { abstract class _SystemConfig implements SystemConfig { const factory _SystemConfig( {required final String domainUrl, - required final bool enableRegistration}) = _$SystemConfigImpl; + required final bool enableRegistration, + final String serverTimezone, + final String adminRoute}) = _$SystemConfigImpl; factory _SystemConfig.fromJson(Map json) = _$SystemConfigImpl.fromJson; @@ -539,6 +585,10 @@ abstract class _SystemConfig implements SystemConfig { @override bool get enableRegistration; @override + String get serverTimezone; + @override + String get adminRoute; + @override @JsonKey(ignore: true) _$$SystemConfigImplCopyWith<_$SystemConfigImpl> get copyWith => throw _privateConstructorUsedError; @@ -831,6 +881,7 @@ mixin _$ChatsModuleConfig { int get maxGroupParticipants => throw _privateConstructorUsedError; bool get allowChatToGroupConversion => throw _privateConstructorUsedError; bool get enableFolders => throw _privateConstructorUsedError; + bool get enableAutoClean => throw _privateConstructorUsedError; Map toJson() => throw _privateConstructorUsedError; @JsonKey(ignore: true) @@ -848,7 +899,8 @@ abstract class $ChatsModuleConfigCopyWith<$Res> { {bool supportGroups, int maxGroupParticipants, bool allowChatToGroupConversion, - bool enableFolders}); + bool enableFolders, + bool enableAutoClean}); } /// @nodoc @@ -868,6 +920,7 @@ class _$ChatsModuleConfigCopyWithImpl<$Res, $Val extends ChatsModuleConfig> Object? maxGroupParticipants = null, Object? allowChatToGroupConversion = null, Object? enableFolders = null, + Object? enableAutoClean = null, }) { return _then(_value.copyWith( supportGroups: null == supportGroups @@ -886,6 +939,10 @@ class _$ChatsModuleConfigCopyWithImpl<$Res, $Val extends ChatsModuleConfig> ? _value.enableFolders : enableFolders // ignore: cast_nullable_to_non_nullable as bool, + enableAutoClean: null == enableAutoClean + ? _value.enableAutoClean + : enableAutoClean // ignore: cast_nullable_to_non_nullable + as bool, ) as $Val); } } @@ -902,7 +959,8 @@ abstract class _$$ChatsModuleConfigImplCopyWith<$Res> {bool supportGroups, int maxGroupParticipants, bool allowChatToGroupConversion, - bool enableFolders}); + bool enableFolders, + bool enableAutoClean}); } /// @nodoc @@ -920,6 +978,7 @@ class __$$ChatsModuleConfigImplCopyWithImpl<$Res> Object? maxGroupParticipants = null, Object? allowChatToGroupConversion = null, Object? enableFolders = null, + Object? enableAutoClean = null, }) { return _then(_$ChatsModuleConfigImpl( supportGroups: null == supportGroups @@ -938,6 +997,10 @@ class __$$ChatsModuleConfigImplCopyWithImpl<$Res> ? _value.enableFolders : enableFolders // ignore: cast_nullable_to_non_nullable as bool, + enableAutoClean: null == enableAutoClean + ? _value.enableAutoClean + : enableAutoClean // ignore: cast_nullable_to_non_nullable + as bool, )); } } @@ -949,7 +1012,8 @@ class _$ChatsModuleConfigImpl implements _ChatsModuleConfig { {required this.supportGroups, required this.maxGroupParticipants, required this.allowChatToGroupConversion, - required this.enableFolders}); + required this.enableFolders, + this.enableAutoClean = false}); factory _$ChatsModuleConfigImpl.fromJson(Map json) => _$$ChatsModuleConfigImplFromJson(json); @@ -962,10 +1026,13 @@ class _$ChatsModuleConfigImpl implements _ChatsModuleConfig { final bool allowChatToGroupConversion; @override final bool enableFolders; + @override + @JsonKey() + final bool enableAutoClean; @override String toString() { - return 'ChatsModuleConfig(supportGroups: $supportGroups, maxGroupParticipants: $maxGroupParticipants, allowChatToGroupConversion: $allowChatToGroupConversion, enableFolders: $enableFolders)'; + return 'ChatsModuleConfig(supportGroups: $supportGroups, maxGroupParticipants: $maxGroupParticipants, allowChatToGroupConversion: $allowChatToGroupConversion, enableFolders: $enableFolders, enableAutoClean: $enableAutoClean)'; } @override @@ -982,13 +1049,20 @@ class _$ChatsModuleConfigImpl implements _ChatsModuleConfig { other.allowChatToGroupConversion == allowChatToGroupConversion) && (identical(other.enableFolders, enableFolders) || - other.enableFolders == enableFolders)); + other.enableFolders == enableFolders) && + (identical(other.enableAutoClean, enableAutoClean) || + other.enableAutoClean == enableAutoClean)); } @JsonKey(ignore: true) @override - int get hashCode => Object.hash(runtimeType, supportGroups, - maxGroupParticipants, allowChatToGroupConversion, enableFolders); + int get hashCode => Object.hash( + runtimeType, + supportGroups, + maxGroupParticipants, + allowChatToGroupConversion, + enableFolders, + enableAutoClean); @JsonKey(ignore: true) @override @@ -1010,7 +1084,8 @@ abstract class _ChatsModuleConfig implements ChatsModuleConfig { {required final bool supportGroups, required final int maxGroupParticipants, required final bool allowChatToGroupConversion, - required final bool enableFolders}) = _$ChatsModuleConfigImpl; + required final bool enableFolders, + final bool enableAutoClean}) = _$ChatsModuleConfigImpl; factory _ChatsModuleConfig.fromJson(Map json) = _$ChatsModuleConfigImpl.fromJson; @@ -1024,6 +1099,8 @@ abstract class _ChatsModuleConfig implements ChatsModuleConfig { @override bool get enableFolders; @override + bool get enableAutoClean; + @override @JsonKey(ignore: true) _$$ChatsModuleConfigImplCopyWith<_$ChatsModuleConfigImpl> get copyWith => throw _privateConstructorUsedError; @@ -1050,6 +1127,7 @@ mixin _$MessagesConfig { bool get allowLinks => throw _privateConstructorUsedError; bool get allowPolls => throw _privateConstructorUsedError; bool get allowPinning => throw _privateConstructorUsedError; + int get maxFileSize => throw _privateConstructorUsedError; Map toJson() => throw _privateConstructorUsedError; @JsonKey(ignore: true) @@ -1078,7 +1156,8 @@ abstract class $MessagesConfigCopyWith<$Res> { bool forbidCopying, bool allowLinks, bool allowPolls, - bool allowPinning}); + bool allowPinning, + int maxFileSize}); } /// @nodoc @@ -1109,6 +1188,7 @@ class _$MessagesConfigCopyWithImpl<$Res, $Val extends MessagesConfig> Object? allowLinks = null, Object? allowPolls = null, Object? allowPinning = null, + Object? maxFileSize = null, }) { return _then(_value.copyWith( dailyMessageLimitPerUser: null == dailyMessageLimitPerUser @@ -1171,6 +1251,10 @@ class _$MessagesConfigCopyWithImpl<$Res, $Val extends MessagesConfig> ? _value.allowPinning : allowPinning // ignore: cast_nullable_to_non_nullable as bool, + maxFileSize: null == maxFileSize + ? _value.maxFileSize + : maxFileSize // ignore: cast_nullable_to_non_nullable + as int, ) as $Val); } } @@ -1198,7 +1282,8 @@ abstract class _$$MessagesConfigImplCopyWith<$Res> bool forbidCopying, bool allowLinks, bool allowPolls, - bool allowPinning}); + bool allowPinning, + int maxFileSize}); } /// @nodoc @@ -1227,6 +1312,7 @@ class __$$MessagesConfigImplCopyWithImpl<$Res> Object? allowLinks = null, Object? allowPolls = null, Object? allowPinning = null, + Object? maxFileSize = null, }) { return _then(_$MessagesConfigImpl( dailyMessageLimitPerUser: null == dailyMessageLimitPerUser @@ -1289,6 +1375,10 @@ class __$$MessagesConfigImplCopyWithImpl<$Res> ? _value.allowPinning : allowPinning // ignore: cast_nullable_to_non_nullable as bool, + maxFileSize: null == maxFileSize + ? _value.maxFileSize + : maxFileSize // ignore: cast_nullable_to_non_nullable + as int, )); } } @@ -1311,7 +1401,8 @@ class _$MessagesConfigImpl implements _MessagesConfig { required this.forbidCopying, required this.allowLinks, required this.allowPolls, - required this.allowPinning}) + required this.allowPinning, + this.maxFileSize = 0}) : _allowedMediaTypes = allowedMediaTypes; factory _$MessagesConfigImpl.fromJson(Map json) => @@ -1354,10 +1445,13 @@ class _$MessagesConfigImpl implements _MessagesConfig { final bool allowPolls; @override final bool allowPinning; + @override + @JsonKey() + final int maxFileSize; @override String toString() { - return 'MessagesConfig(dailyMessageLimitPerUser: $dailyMessageLimitPerUser, chatMessageLimit: $chatMessageLimit, allowMedia: $allowMedia, maxMediaSizeBytes: $maxMediaSizeBytes, allowedMediaTypes: $allowedMediaTypes, allowVoiceMessages: $allowVoiceMessages, allowForwarding: $allowForwarding, allowReactions: $allowReactions, allowReplies: $allowReplies, allowQuoting: $allowQuoting, allowMessageDeletion: $allowMessageDeletion, forbidCopying: $forbidCopying, allowLinks: $allowLinks, allowPolls: $allowPolls, allowPinning: $allowPinning)'; + return 'MessagesConfig(dailyMessageLimitPerUser: $dailyMessageLimitPerUser, chatMessageLimit: $chatMessageLimit, allowMedia: $allowMedia, maxMediaSizeBytes: $maxMediaSizeBytes, allowedMediaTypes: $allowedMediaTypes, allowVoiceMessages: $allowVoiceMessages, allowForwarding: $allowForwarding, allowReactions: $allowReactions, allowReplies: $allowReplies, allowQuoting: $allowQuoting, allowMessageDeletion: $allowMessageDeletion, forbidCopying: $forbidCopying, allowLinks: $allowLinks, allowPolls: $allowPolls, allowPinning: $allowPinning, maxFileSize: $maxFileSize)'; } @override @@ -1395,7 +1489,9 @@ class _$MessagesConfigImpl implements _MessagesConfig { (identical(other.allowPolls, allowPolls) || other.allowPolls == allowPolls) && (identical(other.allowPinning, allowPinning) || - other.allowPinning == allowPinning)); + other.allowPinning == allowPinning) && + (identical(other.maxFileSize, maxFileSize) || + other.maxFileSize == maxFileSize)); } @JsonKey(ignore: true) @@ -1416,7 +1512,8 @@ class _$MessagesConfigImpl implements _MessagesConfig { forbidCopying, allowLinks, allowPolls, - allowPinning); + allowPinning, + maxFileSize); @JsonKey(ignore: true) @override @@ -1449,7 +1546,8 @@ abstract class _MessagesConfig implements MessagesConfig { required final bool forbidCopying, required final bool allowLinks, required final bool allowPolls, - required final bool allowPinning}) = _$MessagesConfigImpl; + required final bool allowPinning, + final int maxFileSize}) = _$MessagesConfigImpl; factory _MessagesConfig.fromJson(Map json) = _$MessagesConfigImpl.fromJson; @@ -1485,6 +1583,8 @@ abstract class _MessagesConfig implements MessagesConfig { @override bool get allowPinning; @override + int get maxFileSize; + @override @JsonKey(ignore: true) _$$MessagesConfigImplCopyWith<_$MessagesConfigImpl> get copyWith => throw _privateConstructorUsedError; @@ -1502,6 +1602,8 @@ mixin _$WebRtcConfig { bool get enableScreenSharing => throw _privateConstructorUsedError; String get turnHost => throw _privateConstructorUsedError; int get turnPort => throw _privateConstructorUsedError; + String get turnUser => throw _privateConstructorUsedError; + String get turnSecret => throw _privateConstructorUsedError; Map toJson() => throw _privateConstructorUsedError; @JsonKey(ignore: true) @@ -1521,7 +1623,9 @@ abstract class $WebRtcConfigCopyWith<$Res> { bool enableVideoCalls, bool enableScreenSharing, String turnHost, - int turnPort}); + int turnPort, + String turnUser, + String turnSecret}); } /// @nodoc @@ -1543,6 +1647,8 @@ class _$WebRtcConfigCopyWithImpl<$Res, $Val extends WebRtcConfig> Object? enableScreenSharing = null, Object? turnHost = null, Object? turnPort = null, + Object? turnUser = null, + Object? turnSecret = null, }) { return _then(_value.copyWith( enabled: null == enabled @@ -1569,6 +1675,14 @@ class _$WebRtcConfigCopyWithImpl<$Res, $Val extends WebRtcConfig> ? _value.turnPort : turnPort // ignore: cast_nullable_to_non_nullable as int, + turnUser: null == turnUser + ? _value.turnUser + : turnUser // ignore: cast_nullable_to_non_nullable + as String, + turnSecret: null == turnSecret + ? _value.turnSecret + : turnSecret // ignore: cast_nullable_to_non_nullable + as String, ) as $Val); } } @@ -1587,7 +1701,9 @@ abstract class _$$WebRtcConfigImplCopyWith<$Res> bool enableVideoCalls, bool enableScreenSharing, String turnHost, - int turnPort}); + int turnPort, + String turnUser, + String turnSecret}); } /// @nodoc @@ -1607,6 +1723,8 @@ class __$$WebRtcConfigImplCopyWithImpl<$Res> Object? enableScreenSharing = null, Object? turnHost = null, Object? turnPort = null, + Object? turnUser = null, + Object? turnSecret = null, }) { return _then(_$WebRtcConfigImpl( enabled: null == enabled @@ -1633,6 +1751,14 @@ class __$$WebRtcConfigImplCopyWithImpl<$Res> ? _value.turnPort : turnPort // ignore: cast_nullable_to_non_nullable as int, + turnUser: null == turnUser + ? _value.turnUser + : turnUser // ignore: cast_nullable_to_non_nullable + as String, + turnSecret: null == turnSecret + ? _value.turnSecret + : turnSecret // ignore: cast_nullable_to_non_nullable + as String, )); } } @@ -1646,7 +1772,9 @@ class _$WebRtcConfigImpl implements _WebRtcConfig { required this.enableVideoCalls, required this.enableScreenSharing, required this.turnHost, - required this.turnPort}); + required this.turnPort, + this.turnUser = '', + this.turnSecret = ''}); factory _$WebRtcConfigImpl.fromJson(Map json) => _$$WebRtcConfigImplFromJson(json); @@ -1663,10 +1791,16 @@ class _$WebRtcConfigImpl implements _WebRtcConfig { final String turnHost; @override final int turnPort; + @override + @JsonKey() + final String turnUser; + @override + @JsonKey() + final String turnSecret; @override String toString() { - return 'WebRtcConfig(enabled: $enabled, enableVoiceCalls: $enableVoiceCalls, enableVideoCalls: $enableVideoCalls, enableScreenSharing: $enableScreenSharing, turnHost: $turnHost, turnPort: $turnPort)'; + return 'WebRtcConfig(enabled: $enabled, enableVoiceCalls: $enableVoiceCalls, enableVideoCalls: $enableVideoCalls, enableScreenSharing: $enableScreenSharing, turnHost: $turnHost, turnPort: $turnPort, turnUser: $turnUser, turnSecret: $turnSecret)'; } @override @@ -1684,13 +1818,25 @@ class _$WebRtcConfigImpl implements _WebRtcConfig { (identical(other.turnHost, turnHost) || other.turnHost == turnHost) && (identical(other.turnPort, turnPort) || - other.turnPort == turnPort)); + other.turnPort == turnPort) && + (identical(other.turnUser, turnUser) || + other.turnUser == turnUser) && + (identical(other.turnSecret, turnSecret) || + other.turnSecret == turnSecret)); } @JsonKey(ignore: true) @override - int get hashCode => Object.hash(runtimeType, enabled, enableVoiceCalls, - enableVideoCalls, enableScreenSharing, turnHost, turnPort); + int get hashCode => Object.hash( + runtimeType, + enabled, + enableVoiceCalls, + enableVideoCalls, + enableScreenSharing, + turnHost, + turnPort, + turnUser, + turnSecret); @JsonKey(ignore: true) @override @@ -1713,7 +1859,9 @@ abstract class _WebRtcConfig implements WebRtcConfig { required final bool enableVideoCalls, required final bool enableScreenSharing, required final String turnHost, - required final int turnPort}) = _$WebRtcConfigImpl; + required final int turnPort, + final String turnUser, + final String turnSecret}) = _$WebRtcConfigImpl; factory _WebRtcConfig.fromJson(Map json) = _$WebRtcConfigImpl.fromJson; @@ -1731,6 +1879,10 @@ abstract class _WebRtcConfig implements WebRtcConfig { @override int get turnPort; @override + String get turnUser; + @override + String get turnSecret; + @override @JsonKey(ignore: true) _$$WebRtcConfigImplCopyWith<_$WebRtcConfigImpl> get copyWith => throw _privateConstructorUsedError; @@ -1744,6 +1896,7 @@ KlipyConfig _$KlipyConfigFromJson(Map json) { mixin _$KlipyConfig { bool get enabled => throw _privateConstructorUsedError; String get appName => throw _privateConstructorUsedError; + String get apiKey => throw _privateConstructorUsedError; Map toJson() => throw _privateConstructorUsedError; @JsonKey(ignore: true) @@ -1757,7 +1910,7 @@ abstract class $KlipyConfigCopyWith<$Res> { KlipyConfig value, $Res Function(KlipyConfig) then) = _$KlipyConfigCopyWithImpl<$Res, KlipyConfig>; @useResult - $Res call({bool enabled, String appName}); + $Res call({bool enabled, String appName, String apiKey}); } /// @nodoc @@ -1775,6 +1928,7 @@ class _$KlipyConfigCopyWithImpl<$Res, $Val extends KlipyConfig> $Res call({ Object? enabled = null, Object? appName = null, + Object? apiKey = null, }) { return _then(_value.copyWith( enabled: null == enabled @@ -1785,6 +1939,10 @@ class _$KlipyConfigCopyWithImpl<$Res, $Val extends KlipyConfig> ? _value.appName : appName // ignore: cast_nullable_to_non_nullable as String, + apiKey: null == apiKey + ? _value.apiKey + : apiKey // ignore: cast_nullable_to_non_nullable + as String, ) as $Val); } } @@ -1797,7 +1955,7 @@ abstract class _$$KlipyConfigImplCopyWith<$Res> __$$KlipyConfigImplCopyWithImpl<$Res>; @override @useResult - $Res call({bool enabled, String appName}); + $Res call({bool enabled, String appName, String apiKey}); } /// @nodoc @@ -1813,6 +1971,7 @@ class __$$KlipyConfigImplCopyWithImpl<$Res> $Res call({ Object? enabled = null, Object? appName = null, + Object? apiKey = null, }) { return _then(_$KlipyConfigImpl( enabled: null == enabled @@ -1823,6 +1982,10 @@ class __$$KlipyConfigImplCopyWithImpl<$Res> ? _value.appName : appName // ignore: cast_nullable_to_non_nullable as String, + apiKey: null == apiKey + ? _value.apiKey + : apiKey // ignore: cast_nullable_to_non_nullable + as String, )); } } @@ -1830,7 +1993,8 @@ class __$$KlipyConfigImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() class _$KlipyConfigImpl implements _KlipyConfig { - const _$KlipyConfigImpl({required this.enabled, required this.appName}); + const _$KlipyConfigImpl( + {required this.enabled, required this.appName, this.apiKey = ''}); factory _$KlipyConfigImpl.fromJson(Map json) => _$$KlipyConfigImplFromJson(json); @@ -1839,10 +2003,13 @@ class _$KlipyConfigImpl implements _KlipyConfig { final bool enabled; @override final String appName; + @override + @JsonKey() + final String apiKey; @override String toString() { - return 'KlipyConfig(enabled: $enabled, appName: $appName)'; + return 'KlipyConfig(enabled: $enabled, appName: $appName, apiKey: $apiKey)'; } @override @@ -1851,12 +2018,13 @@ class _$KlipyConfigImpl implements _KlipyConfig { (other.runtimeType == runtimeType && other is _$KlipyConfigImpl && (identical(other.enabled, enabled) || other.enabled == enabled) && - (identical(other.appName, appName) || other.appName == appName)); + (identical(other.appName, appName) || other.appName == appName) && + (identical(other.apiKey, apiKey) || other.apiKey == apiKey)); } @JsonKey(ignore: true) @override - int get hashCode => Object.hash(runtimeType, enabled, appName); + int get hashCode => Object.hash(runtimeType, enabled, appName, apiKey); @JsonKey(ignore: true) @override @@ -1875,7 +2043,8 @@ class _$KlipyConfigImpl implements _KlipyConfig { abstract class _KlipyConfig implements KlipyConfig { const factory _KlipyConfig( {required final bool enabled, - required final String appName}) = _$KlipyConfigImpl; + required final String appName, + final String apiKey}) = _$KlipyConfigImpl; factory _KlipyConfig.fromJson(Map json) = _$KlipyConfigImpl.fromJson; @@ -1885,6 +2054,8 @@ abstract class _KlipyConfig implements KlipyConfig { @override String get appName; @override + String get apiKey; + @override @JsonKey(ignore: true) _$$KlipyConfigImplCopyWith<_$KlipyConfigImpl> get copyWith => throw _privateConstructorUsedError; @@ -1896,7 +2067,7 @@ ImportConfig _$ImportConfigFromJson(Map json) { /// @nodoc mixin _$ImportConfig { - bool get enabled => throw _privateConstructorUsedError; + bool get enableTelegramImport => throw _privateConstructorUsedError; Map toJson() => throw _privateConstructorUsedError; @JsonKey(ignore: true) @@ -1910,7 +2081,7 @@ abstract class $ImportConfigCopyWith<$Res> { ImportConfig value, $Res Function(ImportConfig) then) = _$ImportConfigCopyWithImpl<$Res, ImportConfig>; @useResult - $Res call({bool enabled}); + $Res call({bool enableTelegramImport}); } /// @nodoc @@ -1926,12 +2097,12 @@ class _$ImportConfigCopyWithImpl<$Res, $Val extends ImportConfig> @pragma('vm:prefer-inline') @override $Res call({ - Object? enabled = null, + Object? enableTelegramImport = null, }) { return _then(_value.copyWith( - enabled: null == enabled - ? _value.enabled - : enabled // ignore: cast_nullable_to_non_nullable + enableTelegramImport: null == enableTelegramImport + ? _value.enableTelegramImport + : enableTelegramImport // ignore: cast_nullable_to_non_nullable as bool, ) as $Val); } @@ -1945,7 +2116,7 @@ abstract class _$$ImportConfigImplCopyWith<$Res> __$$ImportConfigImplCopyWithImpl<$Res>; @override @useResult - $Res call({bool enabled}); + $Res call({bool enableTelegramImport}); } /// @nodoc @@ -1959,12 +2130,12 @@ class __$$ImportConfigImplCopyWithImpl<$Res> @pragma('vm:prefer-inline') @override $Res call({ - Object? enabled = null, + Object? enableTelegramImport = null, }) { return _then(_$ImportConfigImpl( - enabled: null == enabled - ? _value.enabled - : enabled // ignore: cast_nullable_to_non_nullable + enableTelegramImport: null == enableTelegramImport + ? _value.enableTelegramImport + : enableTelegramImport // ignore: cast_nullable_to_non_nullable as bool, )); } @@ -1973,17 +2144,18 @@ class __$$ImportConfigImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() class _$ImportConfigImpl implements _ImportConfig { - const _$ImportConfigImpl({required this.enabled}); + const _$ImportConfigImpl({this.enableTelegramImport = false}); factory _$ImportConfigImpl.fromJson(Map json) => _$$ImportConfigImplFromJson(json); @override - final bool enabled; + @JsonKey() + final bool enableTelegramImport; @override String toString() { - return 'ImportConfig(enabled: $enabled)'; + return 'ImportConfig(enableTelegramImport: $enableTelegramImport)'; } @override @@ -1991,12 +2163,13 @@ class _$ImportConfigImpl implements _ImportConfig { return identical(this, other) || (other.runtimeType == runtimeType && other is _$ImportConfigImpl && - (identical(other.enabled, enabled) || other.enabled == enabled)); + (identical(other.enableTelegramImport, enableTelegramImport) || + other.enableTelegramImport == enableTelegramImport)); } @JsonKey(ignore: true) @override - int get hashCode => Object.hash(runtimeType, enabled); + int get hashCode => Object.hash(runtimeType, enableTelegramImport); @JsonKey(ignore: true) @override @@ -2013,14 +2186,14 @@ class _$ImportConfigImpl implements _ImportConfig { } abstract class _ImportConfig implements ImportConfig { - const factory _ImportConfig({required final bool enabled}) = + const factory _ImportConfig({final bool enableTelegramImport}) = _$ImportConfigImpl; factory _ImportConfig.fromJson(Map json) = _$ImportConfigImpl.fromJson; @override - bool get enabled; + bool get enableTelegramImport; @override @JsonKey(ignore: true) _$$ImportConfigImplCopyWith<_$ImportConfigImpl> get copyWith => diff --git a/client-mobile/lib/features/settings/domain/entities/server_config.g.dart b/client-mobile/lib/features/settings/domain/entities/server_config.g.dart index aace8df..3d28fb1 100644 --- a/client-mobile/lib/features/settings/domain/entities/server_config.g.dart +++ b/client-mobile/lib/features/settings/domain/entities/server_config.g.dart @@ -36,12 +36,16 @@ _$SystemConfigImpl _$$SystemConfigImplFromJson(Map json) => _$SystemConfigImpl( domainUrl: json['domainUrl'] as String, enableRegistration: json['enableRegistration'] as bool, + serverTimezone: json['serverTimezone'] as String? ?? 'UTC', + adminRoute: json['adminRoute'] as String? ?? 'admin', ); Map _$$SystemConfigImplToJson(_$SystemConfigImpl instance) => { 'domainUrl': instance.domainUrl, 'enableRegistration': instance.enableRegistration, + 'serverTimezone': instance.serverTimezone, + 'adminRoute': instance.adminRoute, }; _$StoriesConfigImpl _$$StoriesConfigImplFromJson(Map json) => @@ -75,6 +79,7 @@ _$ChatsModuleConfigImpl _$$ChatsModuleConfigImplFromJson( maxGroupParticipants: (json['maxGroupParticipants'] as num).toInt(), allowChatToGroupConversion: json['allowChatToGroupConversion'] as bool, enableFolders: json['enableFolders'] as bool, + enableAutoClean: json['enableAutoClean'] as bool? ?? false, ); Map _$$ChatsModuleConfigImplToJson( @@ -84,6 +89,7 @@ Map _$$ChatsModuleConfigImplToJson( 'maxGroupParticipants': instance.maxGroupParticipants, 'allowChatToGroupConversion': instance.allowChatToGroupConversion, 'enableFolders': instance.enableFolders, + 'enableAutoClean': instance.enableAutoClean, }; _$MessagesConfigImpl _$$MessagesConfigImplFromJson(Map json) => @@ -106,6 +112,7 @@ _$MessagesConfigImpl _$$MessagesConfigImplFromJson(Map json) => allowLinks: json['allowLinks'] as bool, allowPolls: json['allowPolls'] as bool, allowPinning: json['allowPinning'] as bool, + maxFileSize: (json['maxFileSize'] as num?)?.toInt() ?? 0, ); Map _$$MessagesConfigImplToJson( @@ -126,6 +133,7 @@ Map _$$MessagesConfigImplToJson( 'allowLinks': instance.allowLinks, 'allowPolls': instance.allowPolls, 'allowPinning': instance.allowPinning, + 'maxFileSize': instance.maxFileSize, }; _$WebRtcConfigImpl _$$WebRtcConfigImplFromJson(Map json) => @@ -136,6 +144,8 @@ _$WebRtcConfigImpl _$$WebRtcConfigImplFromJson(Map json) => enableScreenSharing: json['enableScreenSharing'] as bool, turnHost: json['turnHost'] as String, turnPort: (json['turnPort'] as num).toInt(), + turnUser: json['turnUser'] as String? ?? '', + turnSecret: json['turnSecret'] as String? ?? '', ); Map _$$WebRtcConfigImplToJson(_$WebRtcConfigImpl instance) => @@ -146,28 +156,32 @@ Map _$$WebRtcConfigImplToJson(_$WebRtcConfigImpl instance) => 'enableScreenSharing': instance.enableScreenSharing, 'turnHost': instance.turnHost, 'turnPort': instance.turnPort, + 'turnUser': instance.turnUser, + 'turnSecret': instance.turnSecret, }; _$KlipyConfigImpl _$$KlipyConfigImplFromJson(Map json) => _$KlipyConfigImpl( enabled: json['enabled'] as bool, appName: json['appName'] as String, + apiKey: json['apiKey'] as String? ?? '', ); Map _$$KlipyConfigImplToJson(_$KlipyConfigImpl instance) => { 'enabled': instance.enabled, 'appName': instance.appName, + 'apiKey': instance.apiKey, }; _$ImportConfigImpl _$$ImportConfigImplFromJson(Map json) => _$ImportConfigImpl( - enabled: json['enabled'] as bool, + enableTelegramImport: json['enableTelegramImport'] as bool? ?? false, ); Map _$$ImportConfigImplToJson(_$ImportConfigImpl instance) => { - 'enabled': instance.enabled, + 'enableTelegramImport': instance.enableTelegramImport, }; _$FederationConfigImpl _$$FederationConfigImplFromJson( diff --git a/client-mobile/lib/features/settings/domain/repositories/settings_repository.dart b/client-mobile/lib/features/settings/domain/repositories/settings_repository.dart index 9face88..ccad05b 100644 --- a/client-mobile/lib/features/settings/domain/repositories/settings_repository.dart +++ b/client-mobile/lib/features/settings/domain/repositories/settings_repository.dart @@ -7,7 +7,7 @@ abstract class SettingsRepository { Future getLanguageCode(); Future> saveLanguageCode(String code); Future> getServerConfig(); - Future> refreshServerConfig(); + Future> refreshServerConfig(); Future> getNotificationsEnabled(); Future> setNotificationsEnabled(bool enabled); Future> getDarkModeEnabled(); diff --git a/client-mobile/lib/features/settings/presentation/bloc/settings_bloc.dart b/client-mobile/lib/features/settings/presentation/bloc/settings_bloc.dart index c4e2446..0c87ee3 100644 --- a/client-mobile/lib/features/settings/presentation/bloc/settings_bloc.dart +++ b/client-mobile/lib/features/settings/presentation/bloc/settings_bloc.dart @@ -1,4 +1,7 @@ +import 'package:dio/dio.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:get_it/get_it.dart'; +import '../../../../core/errors/errors.dart'; import '../../domain/repositories/settings_repository.dart'; import 'settings_event.dart'; import 'settings_state.dart'; @@ -17,54 +20,64 @@ class SettingsBloc extends Bloc { Future _onStarted(SettingsStarted event, emit) async { emit(const SettingsState.loading()); - + final apiUrl = await _repository.getApiUrl() ?? ''; final languageCode = await _repository.getLanguageCode() ?? 'ru'; + + if (apiUrl.isEmpty) { + emit(SettingsState.loaded( + apiUrl: '', + serverConfig: null, + languageCode: languageCode, + )); + return; + } + final configResult = await _repository.getServerConfig(); - configResult.when( - onSuccess: (config) { - emit(SettingsState.loaded( - apiUrl: apiUrl, - serverConfig: config, - languageCode: languageCode, - )); - }, - onFailure: (error) { - emit(SettingsState.loaded( - apiUrl: apiUrl, - serverConfig: null, - languageCode: languageCode, - error: 'Failed to load server config', - )); - }, - ); + if (configResult.isSuccess) { + emit(SettingsState.loaded( + apiUrl: apiUrl, + serverConfig: configResult.data, + languageCode: languageCode, + connectionStatus: ConnectionStatus.connected, + )); + } else { + emit(SettingsState.loaded( + apiUrl: apiUrl, + serverConfig: null, + languageCode: languageCode, + connectionStatus: ConnectionStatus.error, + error: _errorMessage(configResult.error!), + )); + } } Future _onConfigRequested(SettingsConfigRequested event, emit) async { if (state is! SettingsLoaded) return; final currentState = state as SettingsLoaded; - - emit(const SettingsState.loading()); - final configResult = await _repository.getServerConfig(); - - configResult.when( - onSuccess: (config) { - emit(SettingsState.loaded( - apiUrl: currentState.apiUrl, - serverConfig: config, - languageCode: currentState.languageCode, - )); - }, - onFailure: (error) { - emit(SettingsState.loaded( - apiUrl: currentState.apiUrl, - serverConfig: null, - languageCode: currentState.languageCode, - error: 'Failed to refresh config', - )); - }, - ); + + if (currentState.apiUrl.isEmpty) return; + + emit(currentState.copyWith(connectionStatus: ConnectionStatus.checking)); + final configResult = await _repository.refreshServerConfig(); + + if (configResult.isSuccess) { + emit(SettingsState.loaded( + apiUrl: currentState.apiUrl, + serverConfig: configResult.data, + languageCode: currentState.languageCode, + connectionStatus: ConnectionStatus.connected, + )); + } else { + emit(SettingsState.loaded( + apiUrl: currentState.apiUrl, + serverConfig: null, + languageCode: currentState.languageCode, + connectionStatus: ConnectionStatus.error, + error: _errorMessage(configResult.error!), + )); + } } void _onApiUrlChanged(SettingsApiUrlChanged event, emit) { @@ -74,6 +87,7 @@ class SettingsBloc extends Bloc { apiUrl: event.url, serverConfig: currentState.serverConfig, languageCode: currentState.languageCode, + connectionStatus: ConnectionStatus.unknown, )); } @@ -81,25 +95,64 @@ class SettingsBloc extends Bloc { if (state is! SettingsLoaded) return; final currentState = state as SettingsLoaded; - await _repository.saveApiUrl(event.url); + // Нормализуем URL: убираем дублирование /api и другие проблемные суффиксы + final normalizedUrl = _normalizeApiUrl(event.url); + await _repository.saveApiUrl(normalizedUrl); + + // Обновляем baseUrl у Dio, чтобы последующие запросы шли на новый адрес + final dio = GetIt.instance(); + dio.options.baseUrl = normalizedUrl; + + if (event.url.isEmpty) { + emit(SettingsState.loaded( + apiUrl: '', + serverConfig: null, + languageCode: currentState.languageCode, + connectionStatus: ConnectionStatus.unknown, + )); + return; + } + + // Проверяем подключение к новому адресу emit(SettingsState.loaded( apiUrl: event.url, serverConfig: currentState.serverConfig, languageCode: currentState.languageCode, + connectionStatus: ConnectionStatus.checking, )); + + final configResult = await _repository.refreshServerConfig(); + + if (configResult.isSuccess) { + emit(SettingsState.loaded( + apiUrl: event.url, + serverConfig: configResult.data, + languageCode: currentState.languageCode, + connectionStatus: ConnectionStatus.connected, + )); + } else { + emit(SettingsState.loaded( + apiUrl: event.url, + serverConfig: null, + languageCode: currentState.languageCode, + connectionStatus: ConnectionStatus.error, + error: _errorMessage(configResult.error!), + )); + } } Future _onLanguageChanged(SettingsLanguageChanged event, emit) async { if (state is! SettingsLoaded) return; final currentState = state as SettingsLoaded; - + await _repository.saveLanguageCode(event.code); - + emit(SettingsState.loaded( apiUrl: currentState.apiUrl, serverConfig: currentState.serverConfig, languageCode: event.code, + connectionStatus: currentState.connectionStatus, )); } @@ -107,4 +160,33 @@ class SettingsBloc extends Bloc { add(const SettingsConfigRequested()); await Future.delayed(const Duration(milliseconds: 100)); } + + String _errorMessage(AppError error) => error.when( + unknown: (msg) => msg?.contains('parsing') == true ? 'parsingError' : 'unknownError', + network: (msg) => 'networkError', + unauthorized: (msg) => 'unauthorized', + forbidden: (msg) => 'forbidden', + notFound: (msg) => 'notFound', + server: (code, msg) => 'serverError', + database: (msg) => 'databaseError', + validation: (message, errors) => 'validationError', + parsing: (msg) => 'parsingError', + ); + + String _normalizeApiUrl(String url) { + if (url.isEmpty) return url; + + // Убираем все слэши в конце + String normalized = url.replaceAll(RegExp(r'/+$'), ''); + + // Если URL заканчивается на /api, убираем этот суффикс + // (так как мы всегда добавляем /api к путям при запросе) + if (normalized.endsWith('/api')) { + normalized = normalized.substring(0, normalized.length - 4); + normalized = normalized.replaceAll(RegExp(r'/+$'), ''); + } + + return normalized; + } } + diff --git a/client-mobile/lib/features/settings/presentation/bloc/settings_state.dart b/client-mobile/lib/features/settings/presentation/bloc/settings_state.dart index e213f00..43b993f 100644 --- a/client-mobile/lib/features/settings/presentation/bloc/settings_state.dart +++ b/client-mobile/lib/features/settings/presentation/bloc/settings_state.dart @@ -3,6 +3,8 @@ import '../../domain/entities/server_config.dart'; part 'settings_state.freezed.dart'; +enum ConnectionStatus { unknown, checking, connected, error } + @freezed class SettingsState with _$SettingsState { const factory SettingsState.initial() = SettingsInitial; @@ -12,6 +14,7 @@ class SettingsState with _$SettingsState { required ServerConfig? serverConfig, required String languageCode, String? error, + @Default(ConnectionStatus.unknown) ConnectionStatus connectionStatus, }) = SettingsLoaded; const factory SettingsState.error(String message) = SettingsError; } diff --git a/client-mobile/lib/features/settings/presentation/bloc/settings_state.freezed.dart b/client-mobile/lib/features/settings/presentation/bloc/settings_state.freezed.dart index dd19689..ad0da47 100644 --- a/client-mobile/lib/features/settings/presentation/bloc/settings_state.freezed.dart +++ b/client-mobile/lib/features/settings/presentation/bloc/settings_state.freezed.dart @@ -20,8 +20,12 @@ mixin _$SettingsState { TResult when({ required TResult Function() initial, required TResult Function() loading, - required TResult Function(String apiUrl, ServerConfig? serverConfig, - String languageCode, String? error) + required TResult Function( + String apiUrl, + ServerConfig? serverConfig, + String languageCode, + String? error, + ConnectionStatus connectionStatus) loaded, required TResult Function(String message) error, }) => @@ -30,8 +34,12 @@ mixin _$SettingsState { TResult? whenOrNull({ TResult? Function()? initial, TResult? Function()? loading, - TResult? Function(String apiUrl, ServerConfig? serverConfig, - String languageCode, String? error)? + TResult? Function( + String apiUrl, + ServerConfig? serverConfig, + String languageCode, + String? error, + ConnectionStatus connectionStatus)? loaded, TResult? Function(String message)? error, }) => @@ -40,8 +48,12 @@ mixin _$SettingsState { TResult maybeWhen({ TResult Function()? initial, TResult Function()? loading, - TResult Function(String apiUrl, ServerConfig? serverConfig, - String languageCode, String? error)? + TResult Function( + String apiUrl, + ServerConfig? serverConfig, + String languageCode, + String? error, + ConnectionStatus connectionStatus)? loaded, TResult Function(String message)? error, required TResult orElse(), @@ -132,8 +144,12 @@ class _$SettingsInitialImpl implements SettingsInitial { TResult when({ required TResult Function() initial, required TResult Function() loading, - required TResult Function(String apiUrl, ServerConfig? serverConfig, - String languageCode, String? error) + required TResult Function( + String apiUrl, + ServerConfig? serverConfig, + String languageCode, + String? error, + ConnectionStatus connectionStatus) loaded, required TResult Function(String message) error, }) { @@ -145,8 +161,12 @@ class _$SettingsInitialImpl implements SettingsInitial { TResult? whenOrNull({ TResult? Function()? initial, TResult? Function()? loading, - TResult? Function(String apiUrl, ServerConfig? serverConfig, - String languageCode, String? error)? + TResult? Function( + String apiUrl, + ServerConfig? serverConfig, + String languageCode, + String? error, + ConnectionStatus connectionStatus)? loaded, TResult? Function(String message)? error, }) { @@ -158,8 +178,12 @@ class _$SettingsInitialImpl implements SettingsInitial { TResult maybeWhen({ TResult Function()? initial, TResult Function()? loading, - TResult Function(String apiUrl, ServerConfig? serverConfig, - String languageCode, String? error)? + TResult Function( + String apiUrl, + ServerConfig? serverConfig, + String languageCode, + String? error, + ConnectionStatus connectionStatus)? loaded, TResult Function(String message)? error, required TResult orElse(), @@ -252,8 +276,12 @@ class _$SettingsLoadingImpl implements SettingsLoading { TResult when({ required TResult Function() initial, required TResult Function() loading, - required TResult Function(String apiUrl, ServerConfig? serverConfig, - String languageCode, String? error) + required TResult Function( + String apiUrl, + ServerConfig? serverConfig, + String languageCode, + String? error, + ConnectionStatus connectionStatus) loaded, required TResult Function(String message) error, }) { @@ -265,8 +293,12 @@ class _$SettingsLoadingImpl implements SettingsLoading { TResult? whenOrNull({ TResult? Function()? initial, TResult? Function()? loading, - TResult? Function(String apiUrl, ServerConfig? serverConfig, - String languageCode, String? error)? + TResult? Function( + String apiUrl, + ServerConfig? serverConfig, + String languageCode, + String? error, + ConnectionStatus connectionStatus)? loaded, TResult? Function(String message)? error, }) { @@ -278,8 +310,12 @@ class _$SettingsLoadingImpl implements SettingsLoading { TResult maybeWhen({ TResult Function()? initial, TResult Function()? loading, - TResult Function(String apiUrl, ServerConfig? serverConfig, - String languageCode, String? error)? + TResult Function( + String apiUrl, + ServerConfig? serverConfig, + String languageCode, + String? error, + ConnectionStatus connectionStatus)? loaded, TResult Function(String message)? error, required TResult orElse(), @@ -342,7 +378,8 @@ abstract class _$$SettingsLoadedImplCopyWith<$Res> { {String apiUrl, ServerConfig? serverConfig, String languageCode, - String? error}); + String? error, + ConnectionStatus connectionStatus}); $ServerConfigCopyWith<$Res>? get serverConfig; } @@ -362,6 +399,7 @@ class __$$SettingsLoadedImplCopyWithImpl<$Res> Object? serverConfig = freezed, Object? languageCode = null, Object? error = freezed, + Object? connectionStatus = null, }) { return _then(_$SettingsLoadedImpl( apiUrl: null == apiUrl @@ -380,6 +418,10 @@ class __$$SettingsLoadedImplCopyWithImpl<$Res> ? _value.error : error // ignore: cast_nullable_to_non_nullable as String?, + connectionStatus: null == connectionStatus + ? _value.connectionStatus + : connectionStatus // ignore: cast_nullable_to_non_nullable + as ConnectionStatus, )); } @@ -403,7 +445,8 @@ class _$SettingsLoadedImpl implements SettingsLoaded { {required this.apiUrl, required this.serverConfig, required this.languageCode, - this.error}); + this.error, + this.connectionStatus = ConnectionStatus.unknown}); @override final String apiUrl; @@ -413,10 +456,13 @@ class _$SettingsLoadedImpl implements SettingsLoaded { final String languageCode; @override final String? error; + @override + @JsonKey() + final ConnectionStatus connectionStatus; @override String toString() { - return 'SettingsState.loaded(apiUrl: $apiUrl, serverConfig: $serverConfig, languageCode: $languageCode, error: $error)'; + return 'SettingsState.loaded(apiUrl: $apiUrl, serverConfig: $serverConfig, languageCode: $languageCode, error: $error, connectionStatus: $connectionStatus)'; } @override @@ -429,12 +475,14 @@ class _$SettingsLoadedImpl implements SettingsLoaded { other.serverConfig == serverConfig) && (identical(other.languageCode, languageCode) || other.languageCode == languageCode) && - (identical(other.error, error) || other.error == error)); + (identical(other.error, error) || other.error == error) && + (identical(other.connectionStatus, connectionStatus) || + other.connectionStatus == connectionStatus)); } @override - int get hashCode => - Object.hash(runtimeType, apiUrl, serverConfig, languageCode, error); + int get hashCode => Object.hash( + runtimeType, apiUrl, serverConfig, languageCode, error, connectionStatus); @JsonKey(ignore: true) @override @@ -448,12 +496,17 @@ class _$SettingsLoadedImpl implements SettingsLoaded { TResult when({ required TResult Function() initial, required TResult Function() loading, - required TResult Function(String apiUrl, ServerConfig? serverConfig, - String languageCode, String? error) + required TResult Function( + String apiUrl, + ServerConfig? serverConfig, + String languageCode, + String? error, + ConnectionStatus connectionStatus) loaded, required TResult Function(String message) error, }) { - return loaded(apiUrl, serverConfig, languageCode, this.error); + return loaded( + apiUrl, serverConfig, languageCode, this.error, connectionStatus); } @override @@ -461,12 +514,17 @@ class _$SettingsLoadedImpl implements SettingsLoaded { TResult? whenOrNull({ TResult? Function()? initial, TResult? Function()? loading, - TResult? Function(String apiUrl, ServerConfig? serverConfig, - String languageCode, String? error)? + TResult? Function( + String apiUrl, + ServerConfig? serverConfig, + String languageCode, + String? error, + ConnectionStatus connectionStatus)? loaded, TResult? Function(String message)? error, }) { - return loaded?.call(apiUrl, serverConfig, languageCode, this.error); + return loaded?.call( + apiUrl, serverConfig, languageCode, this.error, connectionStatus); } @override @@ -474,14 +532,19 @@ class _$SettingsLoadedImpl implements SettingsLoaded { TResult maybeWhen({ TResult Function()? initial, TResult Function()? loading, - TResult Function(String apiUrl, ServerConfig? serverConfig, - String languageCode, String? error)? + TResult Function( + String apiUrl, + ServerConfig? serverConfig, + String languageCode, + String? error, + ConnectionStatus connectionStatus)? loaded, TResult Function(String message)? error, required TResult orElse(), }) { if (loaded != null) { - return loaded(apiUrl, serverConfig, languageCode, this.error); + return loaded( + apiUrl, serverConfig, languageCode, this.error, connectionStatus); } return orElse(); } @@ -529,12 +592,14 @@ abstract class SettingsLoaded implements SettingsState { {required final String apiUrl, required final ServerConfig? serverConfig, required final String languageCode, - final String? error}) = _$SettingsLoadedImpl; + final String? error, + final ConnectionStatus connectionStatus}) = _$SettingsLoadedImpl; String get apiUrl; ServerConfig? get serverConfig; String get languageCode; String? get error; + ConnectionStatus get connectionStatus; @JsonKey(ignore: true) _$$SettingsLoadedImplCopyWith<_$SettingsLoadedImpl> get copyWith => throw _privateConstructorUsedError; @@ -606,8 +671,12 @@ class _$SettingsErrorImpl implements SettingsError { TResult when({ required TResult Function() initial, required TResult Function() loading, - required TResult Function(String apiUrl, ServerConfig? serverConfig, - String languageCode, String? error) + required TResult Function( + String apiUrl, + ServerConfig? serverConfig, + String languageCode, + String? error, + ConnectionStatus connectionStatus) loaded, required TResult Function(String message) error, }) { @@ -619,8 +688,12 @@ class _$SettingsErrorImpl implements SettingsError { TResult? whenOrNull({ TResult? Function()? initial, TResult? Function()? loading, - TResult? Function(String apiUrl, ServerConfig? serverConfig, - String languageCode, String? error)? + TResult? Function( + String apiUrl, + ServerConfig? serverConfig, + String languageCode, + String? error, + ConnectionStatus connectionStatus)? loaded, TResult? Function(String message)? error, }) { @@ -632,8 +705,12 @@ class _$SettingsErrorImpl implements SettingsError { TResult maybeWhen({ TResult Function()? initial, TResult Function()? loading, - TResult Function(String apiUrl, ServerConfig? serverConfig, - String languageCode, String? error)? + TResult Function( + String apiUrl, + ServerConfig? serverConfig, + String languageCode, + String? error, + ConnectionStatus connectionStatus)? loaded, TResult Function(String message)? error, required TResult orElse(), diff --git a/client-mobile/lib/features/settings/presentation/pages/settings_page.dart b/client-mobile/lib/features/settings/presentation/pages/settings_page.dart index 0ce2aa5..16f1ff7 100644 --- a/client-mobile/lib/features/settings/presentation/pages/settings_page.dart +++ b/client-mobile/lib/features/settings/presentation/pages/settings_page.dart @@ -1,56 +1,88 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import '../l10n/app_localizations.dart'; +import 'package:get_it/get_it.dart'; + import '../../domain/entities/server_config.dart'; -import '../bloc/settings_bloc.dart'; -import '../bloc/settings_event.dart'; -import '../bloc/settings_state.dart'; +import 'package:messenger_app/features/settings/presentation/bloc/settings_bloc.dart'; +import 'package:messenger_app/features/settings/presentation/bloc/settings_event.dart'; +import 'package:messenger_app/features/settings/presentation/bloc/settings_state.dart'; +import 'package:messenger_app/features/auth/presentation/bloc/auth_bloc.dart'; +import 'package:messenger_app/features/auth/presentation/bloc/auth_state.dart'; +import 'package:messenger_app/features/auth/presentation/bloc/auth_event.dart'; +import 'package:messenger_app/l10n/app_localizations.dart'; + +final sl = GetIt.instance; class SettingsPage extends StatelessWidget { const SettingsPage({super.key}); @override Widget build(BuildContext context) { - return BlocBuilder( - builder: (context, state) { - return state.when( - initial: () => const Center(child: CircularProgressIndicator()), - loading: () => const Center(child: CircularProgressIndicator()), - loaded: (apiUrl, serverConfig, languageCode, error) => _SettingsContent( - apiUrl: apiUrl, - serverConfig: serverConfig, - languageCode: languageCode, - error: error, - ), - error: (message) => Center(child: Text(message)), - ); - }, - ); + // BlocProvider is now at the top level in app.dart + return const _SettingsContent(); } } class _SettingsContent extends StatelessWidget { + const _SettingsContent(); + + @override + Widget build(BuildContext context) { + final l10n = AppLocalizations.of(context)!; + return Scaffold( + appBar: AppBar( + title: Text(l10n.settings), + ), + body: BlocBuilder( + builder: (context, state) { + return state.when( + initial: () => _SettingsContentImpl( + apiUrl: '', + serverConfig: null, + languageCode: 'ru', + connectionStatus: ConnectionStatus.unknown, + ), + loading: () => const Center(child: CircularProgressIndicator()), + loaded: (apiUrl, serverConfig, languageCode, error, connectionStatus) => _SettingsContentImpl( + apiUrl: apiUrl, + serverConfig: serverConfig, + languageCode: languageCode, + connectionStatus: connectionStatus, + connectionError: error, + ), + error: (message) => Center(child: Text('${l10n.error}: $message')), + ); + }, + ), + ); + } +} + +class _SettingsContentImpl extends StatelessWidget { final String apiUrl; final ServerConfig? serverConfig; final String languageCode; - final String? error; + final ConnectionStatus connectionStatus; + final String? connectionError; - const _SettingsContent({ + const _SettingsContentImpl({ required this.apiUrl, required this.serverConfig, required this.languageCode, - this.error, + this.connectionStatus = ConnectionStatus.unknown, + this.connectionError, }); @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context)!; - return ListView( children: [ _SectionHeader(title: l10n.serverSettings), _ApiUrlTile( apiUrl: apiUrl, + connectionStatus: connectionStatus, + connectionError: connectionError, onSave: (url) { context.read().add(SettingsApiUrlSaved(url)); }, @@ -72,16 +104,40 @@ class _SettingsContent extends StatelessWidget { title: l10n.system, icon: Icons.computer, children: [ - _ConfigItem(label: l10n.domainUrl, value: serverConfig!.system.domainUrl), - _ConfigItem(label: l10n.enableRegistration, value: serverConfig!.system.enableRegistration ? l10n.enabled : l10n.disabled), + _ConfigItem( + label: l10n.domainUrl, + value: serverConfig!.system.domainUrl.contains('example.com') ? apiUrl : serverConfig!.system.domainUrl, + ), + _ConfigItem(label: l10n.registrationStatus, value: serverConfig!.system.enableRegistration ? l10n.enabled : l10n.disabled), ], ), _ConfigModuleCard( title: l10n.messages, icon: Icons.message, children: [ - _ConfigItem(label: l10n.enabled, value: serverConfig!.messages.allowMedia ? l10n.enabled : l10n.disabled), - _ConfigItem(label: 'Max media size', value: '${(serverConfig!.messages.maxMediaSizeBytes / 1024 / 1024).toStringAsFixed(1)} MB'), + _ConfigItem( + label: l10n.dailyLimit, + value: serverConfig!.messages.dailyMessageLimitPerUser == 0 ? l10n.noLimit : '${serverConfig!.messages.dailyMessageLimitPerUser}', + ), + _ConfigItem( + label: l10n.historyLimit, + value: serverConfig!.messages.chatMessageLimit == 0 ? l10n.noLimit : '${serverConfig!.messages.chatMessageLimit}', + ), + _ConfigItem( + label: l10n.maxFileSize, + value: '${(serverConfig!.messages.maxFileSize / 1024 / 1024).toStringAsFixed(0)} MB', + ), + _ConfigItem(label: l10n.allowMedia, value: serverConfig!.messages.allowMedia ? l10n.enabled : l10n.disabled), + _ConfigItem(label: l10n.voice, value: serverConfig!.messages.allowVoiceMessages ? l10n.enabled : l10n.disabled), + _ConfigItem(label: l10n.allowForwarding, value: serverConfig!.messages.allowForwarding ? l10n.enabled : l10n.disabled), + _ConfigItem(label: l10n.allowReactions, value: serverConfig!.messages.allowReactions ? l10n.enabled : l10n.disabled), + _ConfigItem(label: l10n.allowReplies, value: serverConfig!.messages.allowReplies ? l10n.enabled : l10n.disabled), + _ConfigItem(label: l10n.allowQuoting, value: serverConfig!.messages.allowQuoting ? l10n.enabled : l10n.disabled), + _ConfigItem(label: l10n.allowMessageDeletion, value: serverConfig!.messages.allowMessageDeletion ? l10n.enabled : l10n.disabled), + _ConfigItem(label: l10n.forbidCopying, value: serverConfig!.messages.forbidCopying ? l10n.enabled : l10n.disabled), + _ConfigItem(label: l10n.allowLinks, value: serverConfig!.messages.allowLinks ? l10n.enabled : l10n.disabled), + _ConfigItem(label: l10n.allowPolls, value: serverConfig!.messages.allowPolls ? l10n.enabled : l10n.disabled), + _ConfigItem(label: l10n.allowPinning, value: serverConfig!.messages.allowPinning ? l10n.enabled : l10n.disabled), ], ), _ConfigModuleCard( @@ -89,8 +145,8 @@ class _SettingsContent extends StatelessWidget { icon: Icons.call, children: [ _ConfigItem(label: l10n.enabled, value: serverConfig!.webRtc.enabled ? l10n.enabled : l10n.disabled), - _ConfigItem(label: 'Voice calls', value: serverConfig!.webRtc.enableVoiceCalls ? l10n.enabled : l10n.disabled), - _ConfigItem(label: 'Video calls', value: serverConfig!.webRtc.enableVideoCalls ? l10n.enabled : l10n.disabled), + _ConfigItem(label: l10n.voice, value: serverConfig!.webRtc.enableVoiceCalls ? l10n.enabled : l10n.disabled), + _ConfigItem(label: l10n.video, value: serverConfig!.webRtc.enableVideoCalls ? l10n.enabled : l10n.disabled), ], ), _ConfigModuleCard( @@ -98,15 +154,15 @@ class _SettingsContent extends StatelessWidget { icon: Icons.auto_stories, children: [ _ConfigItem(label: l10n.enabled, value: serverConfig!.stories.enabled ? l10n.enabled : l10n.disabled), - _ConfigItem(label: 'Lifetime', value: '${serverConfig!.stories.storyLifetimeHours}h'), + _ConfigItem(label: l10n.lifetime, value: '${serverConfig!.stories.storyLifetimeHours}${l10n.hours}'), ], ), _ConfigModuleCard( title: l10n.chatsModule, icon: Icons.chat_bubble, children: [ - _ConfigItem(label: 'Groups', value: serverConfig!.chats.supportGroups ? l10n.enabled : l10n.disabled), - _ConfigItem(label: 'Max participants', value: '${serverConfig!.chats.maxGroupParticipants}'), + _ConfigItem(label: l10n.groups, value: serverConfig!.chats.supportGroups ? l10n.enabled : l10n.disabled), + _ConfigItem(label: l10n.maxParticipants, value: '${serverConfig!.chats.maxGroupParticipants}'), ], ), if (serverConfig!.federation.enabled) @@ -114,7 +170,7 @@ class _SettingsContent extends StatelessWidget { title: l10n.federation, icon: Icons.public, children: [ - _ConfigItem(label: 'Description', value: serverConfig!.federation.serverDescription), + _ConfigItem(label: l10n.description, value: serverConfig!.federation.serverDescription), ], ), const Divider(), @@ -165,19 +221,35 @@ class _SettingsContent extends StatelessWidget { ), const Divider(), - Padding( - padding: const EdgeInsets.all(16), - child: OutlinedButton( - onPressed: () {}, - style: OutlinedButton.styleFrom( - foregroundColor: Colors.red, - side: const BorderSide(color: Colors.red), - ), - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 12), - child: Text(l10n.logout), - ), - ), + BlocBuilder( + builder: (context, authState) { + final isAuthenticated = authState.when( + initial: () => false, + loading: () => false, + authenticated: (_) => true, + unauthenticated: () => false, + error: (_) => false, + ); + + if (!isAuthenticated) return const SizedBox.shrink(); + + return Padding( + padding: const EdgeInsets.all(16), + child: OutlinedButton( + onPressed: () { + context.read().add(const AuthEvent.logoutRequested()); + }, + style: OutlinedButton.styleFrom( + foregroundColor: Colors.red, + side: const BorderSide(color: Colors.red), + ), + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 12), + child: Text(l10n.logout), + ), + ), + ); + }, ), ], ); @@ -208,10 +280,14 @@ class _SectionHeader extends StatelessWidget { class _ApiUrlTile extends StatefulWidget { final String apiUrl; + final ConnectionStatus connectionStatus; + final String? connectionError; final ValueChanged onSave; const _ApiUrlTile({ required this.apiUrl, + required this.connectionStatus, + this.connectionError, required this.onSave, }); @@ -243,10 +319,63 @@ class _ApiUrlTileState extends State<_ApiUrlTile> { super.dispose(); } + Widget _buildStatusIndicator(BuildContext context) { + final l10n = AppLocalizations.of(context)!; + switch (widget.connectionStatus) { + case ConnectionStatus.checking: + return const SizedBox( + width: 16, + height: 16, + child: CircularProgressIndicator(strokeWidth: 2), + ); + case ConnectionStatus.connected: + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon(Icons.check_circle, color: Colors.green[600], size: 18), + const SizedBox(width: 4), + Text( + l10n.connected, + style: TextStyle(color: Colors.green[700], fontSize: 12), + ), + ], + ); + case ConnectionStatus.error: + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon(Icons.error_outline, color: Colors.red[600], size: 18), + const SizedBox(width: 4), + Flexible( + child: Text( + _getLocalError(context, widget.connectionError), + style: TextStyle(color: Colors.red[700], fontSize: 12), + overflow: TextOverflow.ellipsis, + ), + ), + ], + ); + case ConnectionStatus.unknown: + return const SizedBox.shrink(); + } + } + + String _getLocalError(BuildContext context, String? errorKey) { + final l10n = AppLocalizations.of(context)!; + if (errorKey == null) return l10n.serverConnectionError; + + switch (errorKey) { + case 'unknownError': return l10n.unknownError; + case 'networkError': return l10n.networkError; + case 'serverError': return l10n.serverError; + case 'parsingError': return l10n.parsingError; + default: return errorKey; + } + } + @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context)!; - if (_isEditing) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), @@ -287,11 +416,18 @@ class _ApiUrlTileState extends State<_ApiUrlTile> { return ListTile( leading: const Icon(Icons.link), title: Text(l10n.apiUrl), - subtitle: Text( - widget.apiUrl.isEmpty ? l10n.apiUrlHint : widget.apiUrl, - style: TextStyle( - color: widget.apiUrl.isEmpty ? Colors.grey : null, - ), + subtitle: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + widget.apiUrl.isEmpty ? l10n.apiUrlHint : widget.apiUrl, + style: TextStyle( + color: widget.apiUrl.isEmpty ? Colors.grey : null, + ), + ), + const SizedBox(height: 2), + _buildStatusIndicator(context), + ], ), trailing: const Icon(Icons.edit), onTap: () => setState(() => _isEditing = true), @@ -311,7 +447,6 @@ class _LanguageTile extends StatelessWidget { @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context)!; - return ListTile( leading: const Icon(Icons.language), title: Text(l10n.language), diff --git a/client-mobile/lib/internal/di/injection_container.dart b/client-mobile/lib/internal/di/injection_container.dart index 58d0e05..5144383 100644 --- a/client-mobile/lib/internal/di/injection_container.dart +++ b/client-mobile/lib/internal/di/injection_container.dart @@ -3,6 +3,12 @@ import 'package:dio/dio.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../../core/network/api_client.dart'; +import '../../features/auth/data/datasources/auth_local_datasource.dart'; +import '../../features/auth/data/datasources/auth_local_datasource_impl.dart'; +import '../../features/auth/data/datasources/auth_remote_datasource.dart'; +import '../../features/auth/data/datasources/auth_remote_datasource_impl.dart'; +import '../../features/auth/data/repositories/auth_repository_impl.dart'; +import '../../features/auth/domain/repositories/auth_repository.dart'; import '../../features/auth/presentation/bloc/auth_bloc.dart'; import '../../features/chat/presentation/bloc/chat_bloc.dart'; import '../../features/settings/data/datasources/settings_local_datasource.dart'; @@ -25,7 +31,15 @@ Future initDependencies() async { // Core - Dio (with dynamic base URL from settings) sl.registerLazySingleton(() { - final apiUrl = prefs.getString('api_url') ?? 'https://api.messenger.app'; + final prefs = sl(); + var apiUrl = prefs.getString('api_url') ?? 'https://api.messenger.app'; + + // Нормализуем URL: убираем /api в конце если есть + apiUrl = apiUrl.replaceAll(RegExp(r'/+$'), ''); + if (apiUrl.endsWith('/api')) { + apiUrl = apiUrl.substring(0, apiUrl.length - 4).replaceAll(RegExp(r'/+$'), ''); + } + return Dio(BaseOptions( baseUrl: apiUrl, connectTimeout: const Duration(seconds: 30), @@ -46,7 +60,19 @@ Future initDependencies() async { sl.registerFactory(() => SettingsBloc(sl())); // Auth - sl.registerFactory(() => AuthBloc()); + sl.registerLazySingleton( + () => AuthLocalDataSourceImpl(sl()), + ); + sl.registerLazySingleton( + () => AuthRemoteDataSourceImpl(sl()), + ); + sl.registerLazySingleton( + () => AuthRepositoryImpl( + remoteDataSource: sl(), + localDataSource: sl(), + ), + ); + sl.registerFactory(() => AuthBloc(authRepository: sl())); // Chat sl.registerFactory(() => ChatBloc()); diff --git a/client-mobile/lib/internal/router/main_screen.dart b/client-mobile/lib/internal/router/main_screen.dart index b62130a..b347e36 100644 --- a/client-mobile/lib/internal/router/main_screen.dart +++ b/client-mobile/lib/internal/router/main_screen.dart @@ -1,8 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import '../../features/auth/presentation/bloc/auth_bloc.dart'; -import '../../features/auth/presentation/bloc/auth_state.dart'; -import '../../features/auth/presentation/pages/login_page.dart'; import '../../features/settings/presentation/pages/settings_page.dart'; import '../router/chats_placeholder.dart'; @@ -89,16 +85,6 @@ class SettingsTab extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocBuilder( - builder: (context, authState) { - return authState.when( - initial: () => const Center(child: CircularProgressIndicator()), - loading: () => const Center(child: CircularProgressIndicator()), - authenticated: (_) => const SettingsPage(), - unauthenticated: () => const LoginPage(), - error: (_) => const LoginPage(), - ); - }, - ); + return const SettingsPage(); } } diff --git a/client-mobile/lib/l10n/app_localizations.dart b/client-mobile/lib/l10n/app_localizations.dart index 6c5d639..8f57402 100644 --- a/client-mobile/lib/l10n/app_localizations.dart +++ b/client-mobile/lib/l10n/app_localizations.dart @@ -62,7 +62,8 @@ import 'app_localizations_ru.dart'; /// be consistent with the languages listed in the AppLocalizations.supportedLocales /// property. abstract class AppLocalizations { - AppLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString()); + AppLocalizations(String locale) + : localeName = intl.Intl.canonicalizedLocale(locale.toString()); final String localeName; @@ -70,7 +71,8 @@ abstract class AppLocalizations { return Localizations.of(context, AppLocalizations); } - static const LocalizationsDelegate delegate = _AppLocalizationsDelegate(); + static const LocalizationsDelegate delegate = + _AppLocalizationsDelegate(); /// A list of this localizations delegate along with the default localizations /// delegates. @@ -82,7 +84,8 @@ abstract class AppLocalizations { /// 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> localizationsDelegates = >[ + static const List> localizationsDelegates = + >[ delegate, GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate, @@ -97,294 +100,487 @@ abstract class AppLocalizations { /// No description provided for @appTitle. /// - /// In en, this message translates to: - /// **'Messenger'** + /// In ru, this message translates to: + /// **'Мессенджер'** String get appTitle; /// No description provided for @chats. /// - /// In en, this message translates to: - /// **'Chats'** + /// In ru, this message translates to: + /// **'Чаты'** String get chats; /// No description provided for @contacts. /// - /// In en, this message translates to: - /// **'Contacts'** + /// In ru, this message translates to: + /// **'Контакты'** String get contacts; /// No description provided for @settings. /// - /// In en, this message translates to: - /// **'Settings'** + /// In ru, this message translates to: + /// **'Настройки'** String get settings; /// No description provided for @login. /// - /// In en, this message translates to: - /// **'Login'** + /// In ru, this message translates to: + /// **'Вход'** String get login; - /// No description provided for @email. + /// No description provided for @username. /// - /// In en, this message translates to: - /// **'Email'** - String get email; + /// In ru, this message translates to: + /// **'Логин'** + String get username; /// No description provided for @password. /// - /// In en, this message translates to: - /// **'Password'** + /// In ru, this message translates to: + /// **'Пароль'** String get password; /// No description provided for @name. /// - /// In en, this message translates to: - /// **'Name'** + /// In ru, this message translates to: + /// **'Имя'** String get name; /// No description provided for @loginButton. /// - /// In en, this message translates to: - /// **'Sign In'** + /// In ru, this message translates to: + /// **'Войти'** String get loginButton; /// No description provided for @register. /// - /// In en, this message translates to: - /// **'Register'** + /// In ru, this message translates to: + /// **'Зарегистрироваться'** String get register; /// No description provided for @noAccount. /// - /// In en, this message translates to: - /// **'No account? Sign up'** + /// In ru, this message translates to: + /// **'Нет аккаунта? Зарегистрироваться'** String get noAccount; /// No description provided for @logout. /// - /// In en, this message translates to: - /// **'Sign Out'** + /// In ru, this message translates to: + /// **'Выйти из аккаунта'** String get logout; /// No description provided for @serverSettings. /// - /// In en, this message translates to: - /// **'Server Settings'** + /// In ru, this message translates to: + /// **'Настройки сервера'** String get serverSettings; /// No description provided for @apiUrl. /// - /// In en, this message translates to: - /// **'API URL'** + /// In ru, this message translates to: + /// **'Адрес API'** String get apiUrl; /// No description provided for @apiUrlHint. /// - /// In en, this message translates to: + /// In ru, this message translates to: /// **'https://api.example.com'** String get apiUrlHint; /// No description provided for @save. /// - /// In en, this message translates to: - /// **'Save'** + /// In ru, this message translates to: + /// **'Сохранить'** String get save; /// No description provided for @serverConfig. /// - /// In en, this message translates to: - /// **'Server Configuration'** + /// In ru, this message translates to: + /// **'Конфигурация сервера'** String get serverConfig; /// No description provided for @system. /// - /// In en, this message translates to: - /// **'System'** + /// In ru, this message translates to: + /// **'Система'** String get system; /// No description provided for @stories. /// - /// In en, this message translates to: - /// **'Stories'** + /// In ru, this message translates to: + /// **'Истории'** String get stories; /// No description provided for @chatsModule. /// - /// In en, this message translates to: - /// **'Chats'** + /// In ru, this message translates to: + /// **'Чаты'** String get chatsModule; /// No description provided for @messages. /// - /// In en, this message translates to: - /// **'Messages'** + /// In ru, this message translates to: + /// **'Сообщения'** String get messages; /// No description provided for @calls. /// - /// In en, this message translates to: - /// **'Calls'** + /// In ru, this message translates to: + /// **'Звонки'** String get calls; /// No description provided for @klipy. /// - /// In en, this message translates to: - /// **'Klipy'** + /// In ru, this message translates to: + /// **'Клипы'** String get klipy; /// No description provided for @import. /// - /// In en, this message translates to: - /// **'Import'** + /// In ru, this message translates to: + /// **'Импорт'** String get import; /// No description provided for @federation. /// - /// In en, this message translates to: - /// **'Federation'** + /// In ru, this message translates to: + /// **'Федерация'** String get federation; /// No description provided for @domainUrl. /// - /// In en, this message translates to: - /// **'Domain'** + /// In ru, this message translates to: + /// **'Домен'** String get domainUrl; - /// No description provided for @enableRegistration. + /// No description provided for @registrationStatus. /// - /// In en, this message translates to: - /// **'Registration Enabled'** - String get enableRegistration; + /// In ru, this message translates to: + /// **'Регистрация'** + String get registrationStatus; /// No description provided for @enabled. /// - /// In en, this message translates to: - /// **'Enabled'** + /// In ru, this message translates to: + /// **'Включено'** String get enabled; /// No description provided for @disabled. /// - /// In en, this message translates to: - /// **'Disabled'** + /// In ru, this message translates to: + /// **'Отключено'** String get disabled; /// No description provided for @language. /// - /// In en, this message translates to: - /// **'Language'** + /// In ru, this message translates to: + /// **'Язык'** String get language; /// No description provided for @russian. /// - /// In en, this message translates to: + /// In ru, this message translates to: /// **'Русский'** String get russian; /// No description provided for @english. /// - /// In en, this message translates to: + /// In ru, this message translates to: /// **'English'** String get english; /// No description provided for @notifications. /// - /// In en, this message translates to: - /// **'Notifications'** + /// In ru, this message translates to: + /// **'Уведомления'** String get notifications; /// No description provided for @privacy. /// - /// In en, this message translates to: - /// **'Privacy'** + /// In ru, this message translates to: + /// **'Конфиденциальность'** String get privacy; /// No description provided for @soundsAndVibration. /// - /// In en, this message translates to: - /// **'Sounds & Vibration'** + /// In ru, this message translates to: + /// **'Звуки и вибрация'** String get soundsAndVibration; /// No description provided for @dataAndStorage. /// - /// In en, this message translates to: - /// **'Data & Storage'** + /// In ru, this message translates to: + /// **'Данные и память'** String get dataAndStorage; /// No description provided for @aboutApp. /// - /// In en, this message translates to: - /// **'About App'** + /// In ru, this message translates to: + /// **'О приложении'** String get aboutApp; /// No description provided for @help. /// - /// In en, this message translates to: - /// **'Help'** + /// In ru, this message translates to: + /// **'Помощь'** String get help; /// No description provided for @version. /// - /// In en, this message translates to: - /// **'Version'** + /// In ru, this message translates to: + /// **'Версия'** String get version; /// No description provided for @loading. /// - /// In en, this message translates to: - /// **'Loading...'** + /// In ru, this message translates to: + /// **'Загрузка...'** String get loading; /// No description provided for @error. /// - /// In en, this message translates to: - /// **'Error'** + /// In ru, this message translates to: + /// **'Ошибка'** String get error; /// No description provided for @retry. /// - /// In en, this message translates to: - /// **'Retry'** + /// In ru, this message translates to: + /// **'Повторить'** String get retry; /// No description provided for @noChats. /// - /// In en, this message translates to: - /// **'No chats yet'** + /// In ru, this message translates to: + /// **'У вас пока нет чатов'** String get noChats; /// No description provided for @inDevelopment. /// - /// In en, this message translates to: - /// **'In development'** + /// In ru, this message translates to: + /// **'Функция в разработке'** String get inDevelopment; /// No description provided for @user. /// - /// In en, this message translates to: - /// **'User'** + /// In ru, this message translates to: + /// **'Пользователь'** String get user; /// No description provided for @edit. /// - /// In en, this message translates to: - /// **'Edit'** + /// In ru, this message translates to: + /// **'Редактировать'** String get edit; /// No description provided for @serverConnectionError. /// - /// In en, this message translates to: - /// **'Server connection error'** + /// In ru, this message translates to: + /// **'Ошибка подключения к серверу'** String get serverConnectionError; + /// No description provided for @connected. + /// + /// In ru, this message translates to: + /// **'Подключено'** + String get connected; + + /// No description provided for @unknownError. + /// + /// In ru, this message translates to: + /// **'Неизвестная ошибка'** + String get unknownError; + + /// No description provided for @networkError. + /// + /// In ru, this message translates to: + /// **'Ошибка сети'** + String get networkError; + + /// No description provided for @serverError. + /// + /// In ru, this message translates to: + /// **'Ошибка сервера'** + String get serverError; + + /// No description provided for @parsingError. + /// + /// In ru, this message translates to: + /// **'Ошибка обработки данных'** + String get parsingError; + + /// No description provided for @voice. + /// + /// In ru, this message translates to: + /// **'Голосовые вызовы'** + String get voice; + + /// No description provided for @video. + /// + /// In ru, this message translates to: + /// **'Видеовызовы'** + String get video; + + /// No description provided for @lifetime. + /// + /// In ru, this message translates to: + /// **'Время жизни'** + String get lifetime; + + /// No description provided for @groups. + /// + /// In ru, this message translates to: + /// **'Группы'** + String get groups; + + /// No description provided for @maxParticipants. + /// + /// In ru, this message translates to: + /// **'Макс. участников'** + String get maxParticipants; + + /// No description provided for @hours. + /// + /// In ru, this message translates to: + /// **'ч.'** + String get hours; + + /// No description provided for @dailyLimit. + /// + /// In ru, this message translates to: + /// **'Дневной лимит'** + String get dailyLimit; + + /// No description provided for @historyLimit. + /// + /// In ru, this message translates to: + /// **'Лимит истории'** + String get historyLimit; + + /// No description provided for @maxFileSize. + /// + /// In ru, this message translates to: + /// **'Макс. файл'** + String get maxFileSize; + + /// No description provided for @noLimit. + /// + /// In ru, this message translates to: + /// **'Без лимита'** + String get noLimit; + + /// No description provided for @allowForwarding. + /// + /// In ru, this message translates to: + /// **'Пересылка'** + String get allowForwarding; + + /// No description provided for @allowReactions. + /// + /// In ru, this message translates to: + /// **'Реакции'** + String get allowReactions; + + /// No description provided for @allowReplies. + /// + /// In ru, this message translates to: + /// **'Ответы'** + String get allowReplies; + + /// No description provided for @allowQuoting. + /// + /// In ru, this message translates to: + /// **'Цитирование'** + String get allowQuoting; + + /// No description provided for @allowMessageDeletion. + /// + /// In ru, this message translates to: + /// **'Удаление'** + String get allowMessageDeletion; + + /// No description provided for @forbidCopying. + /// + /// In ru, this message translates to: + /// **'Запрет копирования'** + String get forbidCopying; + + /// No description provided for @allowLinks. + /// + /// In ru, this message translates to: + /// **'Ссылки'** + String get allowLinks; + + /// No description provided for @allowPolls. + /// + /// In ru, this message translates to: + /// **'Опросы'** + String get allowPolls; + + /// No description provided for @allowPinning. + /// + /// In ru, this message translates to: + /// **'Закрепы'** + String get allowPinning; + + /// No description provided for @allowMedia. + /// + /// In ru, this message translates to: + /// **'Медиа'** + String get allowMedia; + + /// No description provided for @description. + /// + /// In ru, this message translates to: + /// **'Описание'** + String get description; + + /// No description provided for @server. + /// + /// In ru, this message translates to: + /// **'Сервер'** + String get server; + + /// No description provided for @notSpecified. + /// + /// In ru, this message translates to: + /// **'не указан'** + String get notSpecified; + /// No description provided for @settingsSaved. /// - /// In en, this message translates to: - /// **'Settings saved'** + /// In ru, this message translates to: + /// **'Настройки сохранены'** String get settingsSaved; + + /// No description provided for @enterUsername. + /// + /// In ru, this message translates to: + /// **'Введите логин'** + String get enterUsername; + + /// No description provided for @invalidUsername. + /// + /// In ru, this message translates to: + /// **'Логин должен быть от 3 символов и без кириллицы'** + String get invalidUsername; + + /// No description provided for @loginFailed. + /// + /// In ru, this message translates to: + /// **'Ошибка входа. Проверьте логин и пароль'** + String get loginFailed; + + /// No description provided for @registrationFailed. + /// + /// In ru, this message translates to: + /// **'Ошибка регистрации'** + String get registrationFailed; } -class _AppLocalizationsDelegate extends LocalizationsDelegate { +class _AppLocalizationsDelegate + extends LocalizationsDelegate { const _AppLocalizationsDelegate(); @override @@ -393,25 +589,25 @@ class _AppLocalizationsDelegate extends LocalizationsDelegate } @override - bool isSupported(Locale locale) => ['en', 'ru'].contains(locale.languageCode); + bool isSupported(Locale locale) => + ['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(); + 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.' - ); + '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.'); } diff --git a/client-mobile/lib/l10n/app_localizations_en.dart b/client-mobile/lib/l10n/app_localizations_en.dart index 25720e4..e0458b9 100644 --- a/client-mobile/lib/l10n/app_localizations_en.dart +++ b/client-mobile/lib/l10n/app_localizations_en.dart @@ -24,7 +24,7 @@ class AppLocalizationsEn extends AppLocalizations { String get login => 'Login'; @override - String get email => 'Email'; + String get username => 'Login'; @override String get password => 'Password'; @@ -87,7 +87,7 @@ class AppLocalizationsEn extends AppLocalizations { String get domainUrl => 'Domain'; @override - String get enableRegistration => 'Registration Enabled'; + String get registrationStatus => 'Registration'; @override String get enabled => 'Enabled'; @@ -149,6 +149,103 @@ class AppLocalizationsEn extends AppLocalizations { @override String get serverConnectionError => 'Server connection error'; + @override + String get connected => 'Connected'; + + @override + String get unknownError => 'Unknown error'; + + @override + String get networkError => 'Network error'; + + @override + String get serverError => 'Server error'; + + @override + String get parsingError => 'Data parsing error'; + + @override + String get voice => 'Voice Calls'; + + @override + String get video => 'Video Calls'; + + @override + String get lifetime => 'Lifetime'; + + @override + String get groups => 'Groups'; + + @override + String get maxParticipants => 'Max participants'; + + @override + String get hours => 'h'; + + @override + String get dailyLimit => 'Daily Limit'; + + @override + String get historyLimit => 'History Limit'; + + @override + String get maxFileSize => 'Max File Size'; + + @override + String get noLimit => 'No Limit'; + + @override + String get allowForwarding => 'Forwarding'; + + @override + String get allowReactions => 'Reactions'; + + @override + String get allowReplies => 'Replies'; + + @override + String get allowQuoting => 'Quoting'; + + @override + String get allowMessageDeletion => 'Deletion'; + + @override + String get forbidCopying => 'Forbid Copying'; + + @override + String get allowLinks => 'Links'; + + @override + String get allowPolls => 'Polls'; + + @override + String get allowPinning => 'Pins'; + + @override + String get allowMedia => 'Media'; + + @override + String get description => 'Description'; + + @override + String get server => 'Server'; + + @override + String get notSpecified => 'not specified'; + @override String get settingsSaved => 'Settings saved'; + + @override + String get enterUsername => 'Enter login'; + + @override + String get invalidUsername => + 'Login must be at least 3 characters and without Cyrillic'; + + @override + String get loginFailed => 'Login failed. Check your login and password'; + + @override + String get registrationFailed => 'Registration failed'; } diff --git a/client-mobile/lib/l10n/app_localizations_ru.dart b/client-mobile/lib/l10n/app_localizations_ru.dart index d3fab57..9d3ec37 100644 --- a/client-mobile/lib/l10n/app_localizations_ru.dart +++ b/client-mobile/lib/l10n/app_localizations_ru.dart @@ -24,7 +24,7 @@ class AppLocalizationsRu extends AppLocalizations { String get login => 'Вход'; @override - String get email => 'Email'; + String get username => 'Логин'; @override String get password => 'Пароль'; @@ -87,7 +87,7 @@ class AppLocalizationsRu extends AppLocalizations { String get domainUrl => 'Домен'; @override - String get enableRegistration => 'Регистрация включена'; + String get registrationStatus => 'Регистрация'; @override String get enabled => 'Включено'; @@ -149,6 +149,103 @@ class AppLocalizationsRu extends AppLocalizations { @override String get serverConnectionError => 'Ошибка подключения к серверу'; + @override + String get connected => 'Подключено'; + + @override + String get unknownError => 'Неизвестная ошибка'; + + @override + String get networkError => 'Ошибка сети'; + + @override + String get serverError => 'Ошибка сервера'; + + @override + String get parsingError => 'Ошибка обработки данных'; + + @override + String get voice => 'Голосовые вызовы'; + + @override + String get video => 'Видеовызовы'; + + @override + String get lifetime => 'Время жизни'; + + @override + String get groups => 'Группы'; + + @override + String get maxParticipants => 'Макс. участников'; + + @override + String get hours => 'ч.'; + + @override + String get dailyLimit => 'Дневной лимит'; + + @override + String get historyLimit => 'Лимит истории'; + + @override + String get maxFileSize => 'Макс. файл'; + + @override + String get noLimit => 'Без лимита'; + + @override + String get allowForwarding => 'Пересылка'; + + @override + String get allowReactions => 'Реакции'; + + @override + String get allowReplies => 'Ответы'; + + @override + String get allowQuoting => 'Цитирование'; + + @override + String get allowMessageDeletion => 'Удаление'; + + @override + String get forbidCopying => 'Запрет копирования'; + + @override + String get allowLinks => 'Ссылки'; + + @override + String get allowPolls => 'Опросы'; + + @override + String get allowPinning => 'Закрепы'; + + @override + String get allowMedia => 'Медиа'; + + @override + String get description => 'Описание'; + + @override + String get server => 'Сервер'; + + @override + String get notSpecified => 'не указан'; + @override String get settingsSaved => 'Настройки сохранены'; + + @override + String get enterUsername => 'Введите логин'; + + @override + String get invalidUsername => + 'Логин должен быть от 3 символов и без кириллицы'; + + @override + String get loginFailed => 'Ошибка входа. Проверьте логин и пароль'; + + @override + String get registrationFailed => 'Ошибка регистрации'; }