Merge branch 'dev' into Issues-on-payments-timecard-availability-screens-01-02-03-04
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../domain/usecases/get_default_locale_use_case.dart';
|
||||
import '../domain/usecases/get_locale_use_case.dart';
|
||||
import '../domain/usecases/get_supported_locales_use_case.dart';
|
||||
import '../domain/usecases/set_locale_use_case.dart';
|
||||
import '../l10n/strings.g.dart';
|
||||
import 'locale_event.dart';
|
||||
@@ -11,23 +13,39 @@ import 'locale_state.dart';
|
||||
/// It coordinates the flow between user language requests and persistent storage
|
||||
/// using [SetLocaleUseCase] and [GetLocaleUseCase].
|
||||
class LocaleBloc extends Bloc<LocaleEvent, LocaleState> {
|
||||
final GetLocaleUseCase getLocaleUseCase;
|
||||
final SetLocaleUseCase setLocaleUseCase;
|
||||
|
||||
/// Creates a [LocaleBloc] with the required use cases.
|
||||
LocaleBloc({required this.getLocaleUseCase, required this.setLocaleUseCase})
|
||||
: super(LocaleState.initial()) {
|
||||
LocaleBloc({
|
||||
required this.getLocaleUseCase,
|
||||
required this.setLocaleUseCase,
|
||||
required this.getSupportedLocalesUseCase,
|
||||
required this.getDefaultLocaleUseCase,
|
||||
}) : super(LocaleState.initial()) {
|
||||
on<ChangeLocale>(_onChangeLocale);
|
||||
on<LoadLocale>(_onLoadLocale);
|
||||
|
||||
/// Initial event
|
||||
add(const LoadLocale());
|
||||
}
|
||||
|
||||
/// Use case for retrieving the saved locale.
|
||||
final GetLocaleUseCase getLocaleUseCase;
|
||||
|
||||
/// Use case for saving the selected locale.
|
||||
final SetLocaleUseCase setLocaleUseCase;
|
||||
|
||||
/// Use case for retrieving supported locales.
|
||||
final GetSupportedLocalesUseCase getSupportedLocalesUseCase;
|
||||
|
||||
/// Use case for retrieving the default locale.
|
||||
final GetDefaultLocaleUseCase getDefaultLocaleUseCase;
|
||||
|
||||
/// Handles the [ChangeLocale] event by saving it via the use case and emitting new state.
|
||||
Future<void> _onChangeLocale(
|
||||
ChangeLocale event,
|
||||
Emitter<LocaleState> emit,
|
||||
) async {
|
||||
// 1. Update slang settings
|
||||
LocaleSettings.setLocaleRaw(event.locale.languageCode);
|
||||
await LocaleSettings.setLocaleRaw(event.locale.languageCode);
|
||||
|
||||
// 2. Persist using Use Case
|
||||
await setLocaleUseCase(event.locale);
|
||||
@@ -46,11 +64,14 @@ class LocaleBloc extends Bloc<LocaleEvent, LocaleState> {
|
||||
LoadLocale event,
|
||||
Emitter<LocaleState> emit,
|
||||
) async {
|
||||
final Locale? savedLocale = await getLocaleUseCase();
|
||||
final Locale locale = savedLocale ?? const Locale('en');
|
||||
final Locale savedLocale = await getLocaleUseCase();
|
||||
final List<Locale> supportedLocales = getSupportedLocalesUseCase();
|
||||
|
||||
LocaleSettings.setLocaleRaw(locale.languageCode);
|
||||
await LocaleSettings.setLocaleRaw(savedLocale.languageCode);
|
||||
|
||||
emit(LocaleState(locale: locale, supportedLocales: state.supportedLocales));
|
||||
emit(LocaleState(
|
||||
locale: savedLocale,
|
||||
supportedLocales: supportedLocales,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../l10n/strings.g.dart';
|
||||
|
||||
/// Represents the current state of the application's localization.
|
||||
class LocaleState {
|
||||
/// Creates a [LocaleState] with the specified [locale].
|
||||
const LocaleState({required this.locale, required this.supportedLocales});
|
||||
|
||||
/// The initial state of the application, defaulting to English.
|
||||
factory LocaleState.initial() => LocaleState(
|
||||
locale: AppLocaleUtils.findDeviceLocale().flutterLocale,
|
||||
supportedLocales: AppLocaleUtils.supportedLocales,
|
||||
);
|
||||
|
||||
/// The current active locale.
|
||||
final Locale locale;
|
||||
|
||||
/// The list of supported locales for the application.
|
||||
final List<Locale> supportedLocales;
|
||||
|
||||
/// Creates a [LocaleState] with the specified [locale].
|
||||
const LocaleState({required this.locale, required this.supportedLocales});
|
||||
|
||||
/// The initial state of the application, defaulting to English.
|
||||
factory LocaleState.initial() => LocaleState(
|
||||
locale: const Locale('es'),
|
||||
supportedLocales: AppLocaleUtils.supportedLocales,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import 'dart:ui';
|
||||
import 'package:core_localization/src/l10n/strings.g.dart';
|
||||
|
||||
import '../../domain/repositories/locale_repository_interface.dart';
|
||||
import '../datasources/locale_local_data_source.dart';
|
||||
|
||||
@@ -7,22 +9,36 @@ import '../datasources/locale_local_data_source.dart';
|
||||
/// This class handles the mapping between domain [Locale] objects and the raw
|
||||
/// strings handled by the [LocaleLocalDataSource].
|
||||
class LocaleRepositoryImpl implements LocaleRepositoryInterface {
|
||||
final LocaleLocalDataSource _localDataSource;
|
||||
/// Creates a [LocaleRepositoryImpl] with the provided [localDataSource].
|
||||
LocaleRepositoryImpl({required this.localDataSource});
|
||||
|
||||
/// Creates a [LocaleRepositoryImpl] with the provided [_localDataSource].
|
||||
LocaleRepositoryImpl(this._localDataSource);
|
||||
final LocaleLocalDataSource localDataSource;
|
||||
|
||||
@override
|
||||
Future<void> saveLocale(Locale locale) {
|
||||
return _localDataSource.saveLanguageCode(locale.languageCode);
|
||||
return localDataSource.saveLanguageCode(locale.languageCode);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Locale?> getSavedLocale() async {
|
||||
final String? languageCode = await _localDataSource.getLanguageCode();
|
||||
Future<Locale> getSavedLocale() async {
|
||||
return getDefaultLocale();
|
||||
|
||||
/// TODO: FEATURE_NOT_IMPLEMENTED: Implement saved locale retrieval later
|
||||
final String? languageCode = await localDataSource.getLanguageCode();
|
||||
if (languageCode != null) {
|
||||
return Locale(languageCode);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
Locale getDefaultLocale() {
|
||||
final Locale deviceLocale = AppLocaleUtils.findDeviceLocale().flutterLocale;
|
||||
if (getSupportedLocales().contains(deviceLocale)) {
|
||||
return deviceLocale;
|
||||
}
|
||||
return const Locale('en');
|
||||
}
|
||||
|
||||
@override
|
||||
List<Locale> getSupportedLocales() => AppLocaleUtils.supportedLocales;
|
||||
}
|
||||
|
||||
@@ -13,5 +13,11 @@ abstract interface class LocaleRepositoryInterface {
|
||||
/// Retrieves the saved [locale] from persistent storage.
|
||||
///
|
||||
/// Returns `null` if no locale has been previously saved.
|
||||
Future<Locale?> getSavedLocale();
|
||||
Future<Locale> getSavedLocale();
|
||||
|
||||
/// Retrieves the default [Locale] for the application.
|
||||
Locale getDefaultLocale();
|
||||
|
||||
/// Retrieves the list of supported [Locale]s.
|
||||
List<Locale> getSupportedLocales();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import 'dart:ui';
|
||||
import '../repositories/locale_repository_interface.dart';
|
||||
|
||||
/// Use case to retrieve the default locale.
|
||||
class GetDefaultLocaleUseCase {
|
||||
final LocaleRepositoryInterface _repository;
|
||||
|
||||
/// Creates a [GetDefaultLocaleUseCase] with the required [LocaleRepositoryInterface].
|
||||
GetDefaultLocaleUseCase(this._repository);
|
||||
|
||||
/// Retrieves the default locale.
|
||||
Locale call() {
|
||||
return _repository.getDefaultLocale();
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ class GetLocaleUseCase extends NoInputUseCase<Locale?> {
|
||||
GetLocaleUseCase(this._repository);
|
||||
|
||||
@override
|
||||
Future<Locale?> call() {
|
||||
Future<Locale> call() {
|
||||
return _repository.getSavedLocale();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import 'dart:ui';
|
||||
import '../repositories/locale_repository_interface.dart';
|
||||
|
||||
/// Use case to retrieve the list of supported locales.
|
||||
class GetSupportedLocalesUseCase {
|
||||
final LocaleRepositoryInterface _repository;
|
||||
|
||||
/// Creates a [GetSupportedLocalesUseCase] with the required [LocaleRepositoryInterface].
|
||||
GetSupportedLocalesUseCase(this._repository);
|
||||
|
||||
/// Retrieves the supported locales.
|
||||
List<Locale> call() {
|
||||
return _repository.getSupportedLocales();
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
/// Locales: 2
|
||||
/// Strings: 1038 (519 per locale)
|
||||
///
|
||||
/// Built on 2026-01-28 at 09:41 UTC
|
||||
/// Built on 2026-01-29 at 15:50 UTC
|
||||
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint, unused_import
|
||||
|
||||
@@ -3,7 +3,9 @@ import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'data/datasources/locale_local_data_source.dart';
|
||||
import 'data/repositories_impl/locale_repository_impl.dart';
|
||||
import 'domain/repositories/locale_repository_interface.dart';
|
||||
import 'domain/usecases/get_default_locale_use_case.dart';
|
||||
import 'domain/usecases/get_locale_use_case.dart';
|
||||
import 'domain/usecases/get_supported_locales_use_case.dart';
|
||||
import 'domain/usecases/set_locale_use_case.dart';
|
||||
import 'bloc/locale_bloc.dart';
|
||||
|
||||
@@ -18,28 +20,36 @@ class LocalizationModule extends Module {
|
||||
i.addInstance<SharedPreferencesAsync>(SharedPreferencesAsync());
|
||||
|
||||
// Data Sources
|
||||
i.addSingleton<LocaleLocalDataSource>(
|
||||
i.addLazySingleton<LocaleLocalDataSource>(
|
||||
() => LocaleLocalDataSourceImpl(i.get<SharedPreferencesAsync>()),
|
||||
);
|
||||
|
||||
// Repositories
|
||||
i.addSingleton<LocaleRepositoryInterface>(
|
||||
() => LocaleRepositoryImpl(i.get<LocaleLocalDataSource>()),
|
||||
i.addLazySingleton<LocaleRepositoryInterface>(
|
||||
() => LocaleRepositoryImpl(localDataSource: i.get<LocaleLocalDataSource>()),
|
||||
);
|
||||
|
||||
// Use Cases
|
||||
i.addSingleton<GetLocaleUseCase>(
|
||||
i.addLazySingleton<GetLocaleUseCase>(
|
||||
() => GetLocaleUseCase(i.get<LocaleRepositoryInterface>()),
|
||||
);
|
||||
i.addSingleton<SetLocaleUseCase>(
|
||||
i.addLazySingleton<SetLocaleUseCase>(
|
||||
() => SetLocaleUseCase(i.get<LocaleRepositoryInterface>()),
|
||||
);
|
||||
i.addLazySingleton<GetSupportedLocalesUseCase>(
|
||||
() => GetSupportedLocalesUseCase(i.get<LocaleRepositoryInterface>()),
|
||||
);
|
||||
i.addLazySingleton<GetDefaultLocaleUseCase>(
|
||||
() => GetDefaultLocaleUseCase(i.get<LocaleRepositoryInterface>()),
|
||||
);
|
||||
|
||||
// BLoCs
|
||||
i.addSingleton<LocaleBloc>(
|
||||
i.add<LocaleBloc>(
|
||||
() => LocaleBloc(
|
||||
getLocaleUseCase: i.get<GetLocaleUseCase>(),
|
||||
setLocaleUseCase: i.get<SetLocaleUseCase>(),
|
||||
getSupportedLocalesUseCase: i.get<GetSupportedLocalesUseCase>(),
|
||||
getDefaultLocaleUseCase: i.get<GetDefaultLocaleUseCase>(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user