feat: implement use cases for retrieving default and supported locales

This commit is contained in:
Achintha Isuru
2026-01-28 10:31:55 -05:00
parent e73698e64f
commit 6c65c13f24
8 changed files with 91 additions and 17 deletions

View File

@@ -56,8 +56,7 @@ class AppWidget extends StatelessWidget {
Widget build(BuildContext context) {
return BlocProvider<core_localization.LocaleBloc>(
create: (BuildContext context) =>
Modular.get<core_localization.LocaleBloc>()
..add(const core_localization.LoadLocale()),
Modular.get<core_localization.LocaleBloc>(),
child:
BlocBuilder<
core_localization.LocaleBloc,

View File

@@ -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';
@@ -12,8 +14,12 @@ import 'locale_state.dart';
/// using [SetLocaleUseCase] and [GetLocaleUseCase].
class LocaleBloc extends Bloc<LocaleEvent, LocaleState> {
/// 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);
@@ -27,6 +33,12 @@ class LocaleBloc extends Bloc<LocaleEvent, LocaleState> {
/// 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,
@@ -53,10 +65,16 @@ class LocaleBloc extends Bloc<LocaleEvent, LocaleState> {
Emitter<LocaleState> emit,
) async {
final Locale? savedLocale = await getLocaleUseCase();
final Locale locale = savedLocale ?? const Locale('es');
final Locale defaultLocale = getDefaultLocaleUseCase();
final List<Locale> supportedLocales = getSupportedLocalesUseCase();
final Locale locale = savedLocale ?? defaultLocale;
await LocaleSettings.setLocaleRaw(locale.languageCode);
emit(LocaleState(locale: locale, supportedLocales: state.supportedLocales));
emit(LocaleState(
locale: locale,
supportedLocales: supportedLocales,
));
}
}

View File

@@ -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,
);
}

View File

@@ -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';
@@ -18,11 +20,19 @@ class LocaleRepositoryImpl implements LocaleRepositoryInterface {
}
@override
Future<Locale?> getSavedLocale() async {
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() => AppLocaleUtils.findDeviceLocale().flutterLocale;
@override
List<Locale> getSupportedLocales() => AppLocaleUtils.supportedLocales;
}

View File

@@ -14,4 +14,10 @@ abstract interface class LocaleRepositoryInterface {
///
/// Returns `null` if no locale has been previously saved.
Future<Locale?> getSavedLocale();
/// Retrieves the default [Locale] for the application.
Locale getDefaultLocale();
/// Retrieves the list of supported [Locale]s.
List<Locale> getSupportedLocales();
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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';
@@ -34,12 +36,20 @@ class LocalizationModule extends Module {
i.addLazySingleton<SetLocaleUseCase>(
() => SetLocaleUseCase(i.get<LocaleRepositoryInterface>()),
);
i.addLazySingleton<GetSupportedLocalesUseCase>(
() => GetSupportedLocalesUseCase(i.get<LocaleRepositoryInterface>()),
);
i.addLazySingleton<GetDefaultLocaleUseCase>(
() => GetDefaultLocaleUseCase(i.get<LocaleRepositoryInterface>()),
);
// BLoCs
i.add<LocaleBloc>(
() => LocaleBloc(
getLocaleUseCase: i.get<GetLocaleUseCase>(),
setLocaleUseCase: i.get<SetLocaleUseCase>(),
getSupportedLocalesUseCase: i.get<GetSupportedLocalesUseCase>(),
getDefaultLocaleUseCase: i.get<GetDefaultLocaleUseCase>(),
),
);
}