fix(i18n): normalize translations and fallbacks
Build & Deploy PluriWave / Análisis de código (push) Successful in 38s
Build & Deploy PluriWave / Build APK + AAB release (push) Successful in 2m34s

This commit is contained in:
2026-06-03 21:20:08 +02:00
parent a5475ce118
commit 089b8b4227
46 changed files with 17720 additions and 4869 deletions
+30 -11
View File
@@ -4,15 +4,19 @@ import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart' show Locale;
import 'package:geocoding/geocoding.dart';
import 'package:geolocator/geolocator.dart';
import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:url_launcher/url_launcher.dart';
import '../l10n/display_names.dart';
import '../l10n/gen/app_localizations.dart';
import '../modelos/emisora.dart';
import '../modelos/grupo_favoritos.dart';
import '../modelos/preset_ecualizador.dart';
import '../servicios/servicio_alarmas_android.dart';
import '../servicios/servicio_audio.dart';
import '../servicios/servicio_ecualizador.dart';
import '../servicios/servicio_favoritos.dart';
@@ -57,6 +61,19 @@ class EstadoRadio extends ChangeNotifier {
final ServicioGrabacionRadio grabacion;
final Future<File> Function()? _resolverArchivoCustom;
AppLocalizations get _textos {
final actual = _l10n;
if (actual != null) return actual;
return lookupAppLocalizations(const Locale('es'));
}
void configurarLocalizaciones(AppLocalizations l10n) {
_l10n = l10n;
audio.configurarLocalizaciones(l10n);
grabacion.configurarLocalizaciones(l10n);
ServicioAlarmasAndroid.configurarLocalizaciones(l10n);
}
late final ServicioTimer timer;
StreamSubscription<EstadoReproduccion>? _suscripcionEstadoAudio;
StreamSubscription<EstadoGrabacionRadio>? _suscripcionGrabacion;
@@ -64,6 +81,7 @@ class EstadoRadio extends ChangeNotifier {
int _revisionReproduccion = 0;
Emisora? _emisoraSeleccionada;
String? _emisoraPreferidaUuid;
AppLocalizations? _l10n;
// Errores de reproducción → SnackBar.
final _errorController = StreamController<String>.broadcast();
@@ -237,7 +255,7 @@ class EstadoRadio extends ChangeNotifier {
_suscripcionGrabacion = grabacion.estadoStream.listen((estado) {
if (estado.tipo == EstadoGrabacionRadioTipo.error &&
estado.error != null) {
_errorController.add('Error al grabar la radio: ${estado.error}');
_errorController.add(_textos.radioRecordingError(estado.error!));
}
notifyListeners();
});
@@ -274,7 +292,7 @@ class EstadoRadio extends ChangeNotifier {
_populares = results[0];
_tendencias = results[1];
} catch (_) {
_errorCarga = 'Sin conexión a la API de radio';
_errorCarga = _textos.radioApiConnectionError;
} finally {
_cargandoPopulares = false;
notifyListeners();
@@ -433,7 +451,7 @@ class EstadoRadio extends ChangeNotifier {
);
_resultadosBusqueda = pagina;
} catch (_) {
_errorController.add('Error en la busqueda. Comprueba tu conexion.');
_errorController.add(_textos.radioSearchError);
} finally {
_cargandoBusqueda = false;
notifyListeners();
@@ -468,7 +486,7 @@ class EstadoRadio extends ChangeNotifier {
// _buscarPaginaFiltrada actualiza offset/hayMas usando páginas crudas.
_hayMasBusqueda = _hayMasBusqueda && pagina.isNotEmpty;
} catch (_) {
_errorController.add('No se pudieron cargar mas emisoras.');
_errorController.add(_textos.radioLoadMoreStationsError);
} finally {
_cargandoMasBusqueda = false;
notifyListeners();
@@ -554,7 +572,7 @@ class EstadoRadio extends ChangeNotifier {
}
if (pais == null || pais.isEmpty) {
throw Exception('No se pudo detectar tu region');
throw StateError('nearby-region-not-detected');
}
_paisCercanoDetectado = pais;
_emisorasCercanas = _filtrarMinBitrate(
@@ -562,8 +580,7 @@ class EstadoRadio extends ChangeNotifier {
_ultimoMinBitrateBusqueda,
);
} catch (_) {
_errorCercanas =
'No pudimos detectar emisoras cercanas. Usa filtros por pais.';
_errorCercanas = _textos.radioNearbyStationsError;
_emisorasCercanas = [];
} finally {
_cargandoCercanas = false;
@@ -595,7 +612,9 @@ class EstadoRadio extends ChangeNotifier {
_errorController.add(
mensajeError.isNotEmpty && mensajeError != 'Exception'
? mensajeError
: 'No se puede reproducir "${emisora.nombre}"',
: _textos.radioCannotPlayStation(
localizedStationName(_textos, emisora.nombre),
),
);
notifyListeners();
}
@@ -604,13 +623,13 @@ class EstadoRadio extends ChangeNotifier {
Future<void> iniciarGrabacion({Duration? duracion}) async {
final actual = emisoraActual;
if (actual == null) {
_errorController.add('Primero selecciona una emisora para grabar.');
_errorController.add(_textos.recordingSelectStationFirst);
return;
}
try {
await grabacion.iniciar(actual, duracion: duracion);
} catch (e) {
_errorController.add('No se pudo iniciar la grabación: $e');
_errorController.add(_textos.recordingStartError(e.toString()));
}
}
@@ -898,7 +917,7 @@ class EstadoRadio extends ChangeNotifier {
/// Importa configuración desde un JSON exportado previamente.
Future<void> importarConfig(Map<String, dynamic> data) async {
final version = data['version'] as int? ?? 1;
if (version != 1) throw Exception('Versión de configuración no compatible');
if (version != 1) throw Exception(_textos.unsupportedConfigVersion);
final favRaw = data['favoritos'] as List? ?? [];
for (final raw in favRaw) {